如何根据最顶层的父名称空间注册服务条件
How to register service conditional based on top most parent namespace
我有以下 classes,我在使用 SimpleInjector
.
解决问题时遇到了问题
配置界面
Namespace Infrastructure.Base.Interfaces
public interface ILdapConfigService
{
.....
}
会话界面
Namespace Infrastructure.Base.Interfaces
public interface ISessionService
{
LdapConnection GetConnection();
}
会话实施
Namespace Infrastructure.Base.Services
public class SessionService : ISessionService {
ILdapConfigService _ldapConfigService;
public SessionService (ILdapConfigService ldapConfigService)
{
_ldapConfigService = ldapConfigService;
}
public LdapConnection GetConnection()
{
.........
}
}
配置服务实现 1
namespace Infrastructure.Old.Services
public class OldConfigService : ILdapConfigService
{
....
}
配置服务实现 2
namespace Infrastructure.New.Services
public class NewConfigService : ILdapConfigService
{
....
}
这个想法是让 ISessionService
和 SessionService
在一个基础项目中。然后有不同的项目从基础项目中实现 LdapConfigService
实现 ILdapConfigService
。
不同的项目也将提供使用基础库中的存储库的服务 class。
我需要知道如何注册这些接口,或者甚至可以这样注册吗?
Infrastructure.New.Service.SomeService
使用 Infrastructure.Base.Interfaces.IRepository
。
Infrastructure.Old.Service.SomeOtherService
使用 Infrastructure.Base.Interfaces.IRepository
.
Infrastructure.Base.Repositories.Repository
实现 Infrastructure.Base.Interfaces.IRepository
。
Infrastructure.Base.Repositories.Repository
使用 Infrastructure.Base.Interfaces.ISessionService
.
Infrastructure.Base.Services.SessionService
实施 Infrastructure.Base.Interfaces.ISessionService
。
Infrastructure.Base.Services.SessionService
使用 Infrastructure.Base.Interfaces.ILdapConfigService
.
Infrastructure.New.Services.LdapConfigService
实施 Infrastructure.Base.Interfaces.ILdapConfigService
.
Infrastructure.Old.Services.LdapConfigService
实施 Infrastructure.Base.Interfaces.ILdapConfigService
.
如何使用 Simple Injector
注册此逻辑。我使用了 RegisterConditional
但这不太奏效,因为 ILdapConfigService
的消费者位于 base.
container.RegisterConditional<
ILdapConfigService,
Old.Services.LdapConfigService>(
c => c.Consumer.ImplementationType.Namespace.Contains("Old"));
container.RegisterConditional<
ILdapConfigService,
New.Services.LdapConfigService>(
c => c.Consumer.ImplementationType.Namespace.Contains("New"));
container.Register<ISessionService, SessionService>();
container.Register<ILdapRepository, LdapRepository>();
每个 LdapConfigService
与一个 app.config
对话,所有重要信息都加载到其中。
Base 完成 OpenLdap
的整个实现,但 Config 需要注入 SessionService
以便它与正确的服务器通信。谁知道抽象会变得如此复杂。
我的设计模式可能有缺陷吗?
Is my design pattern perhaps flawed?
只要你确定你没有违反 Liskov 替换原则,我就找不到它的任何缺陷,尽管这种设计确实让配置容器变得有点困难。
我认为这里的技巧是创建两个 ISessionService
实现;一个用于 New
东西,一个用于 Old
东西。这使您可以根据类型进行区分。这是必需的,因为 Simple Injector 的 RegisterConditional
有限制,只允许您查看注册的直接消费者类型。您正在有条件地注册 ILdapConfigService
,但它总是被注入 SessionService
。通过为每个 ILdpConfigService
提供自己的 ISessionService
,您可以根据 ISessionSerice
.
的消费者创建条件
Simple Injector 的这种限制是故意的,存在是为了防止用户进行无效配置。例如,如果SessionService
被注册为单例,它不可能有两个不同的ILdapConfigServices
。
由于创建两个 ISessionService
实现是一个 'configuration trick',您可以简单地将第二个实现定义为组合根的一部分并从第一个实现继承。通过这样做,您可以根据类型进行匹配,如下所示:
class NewSessionService : SessionService {
public NewSessionService(ILdabConfigService s) { ... }
}
container.RegisterConditional<ISessionService, SessionService>(
c => c.Consumer.ImplementationType.Namespace.Contains("Old"));
container.RegisterConditional<ILdabConfigServices, Old.LdapConfigService>(
c => c.Consumer.ImplementationType == typeof(SessionService));
container.RegisterConditional<ISessionService, NewSessionService>(
c => c.Consumer.ImplementationType.Namespace.Contains("New"));
container.RegisterConditional<ILdabConfigServices, New.LdapConfigService>(
c => c.Consumer.ImplementationType == typeof(NewSessionService));
我有以下 classes,我在使用 SimpleInjector
.
配置界面
Namespace Infrastructure.Base.Interfaces
public interface ILdapConfigService
{
.....
}
会话界面
Namespace Infrastructure.Base.Interfaces
public interface ISessionService
{
LdapConnection GetConnection();
}
会话实施
Namespace Infrastructure.Base.Services
public class SessionService : ISessionService {
ILdapConfigService _ldapConfigService;
public SessionService (ILdapConfigService ldapConfigService)
{
_ldapConfigService = ldapConfigService;
}
public LdapConnection GetConnection()
{
.........
}
}
配置服务实现 1
namespace Infrastructure.Old.Services
public class OldConfigService : ILdapConfigService
{
....
}
配置服务实现 2
namespace Infrastructure.New.Services
public class NewConfigService : ILdapConfigService
{
....
}
这个想法是让 ISessionService
和 SessionService
在一个基础项目中。然后有不同的项目从基础项目中实现 LdapConfigService
实现 ILdapConfigService
。
不同的项目也将提供使用基础库中的存储库的服务 class。
我需要知道如何注册这些接口,或者甚至可以这样注册吗?
Infrastructure.New.Service.SomeService
使用 Infrastructure.Base.Interfaces.IRepository
。
Infrastructure.Old.Service.SomeOtherService
使用 Infrastructure.Base.Interfaces.IRepository
.
Infrastructure.Base.Repositories.Repository
实现 Infrastructure.Base.Interfaces.IRepository
。
Infrastructure.Base.Repositories.Repository
使用 Infrastructure.Base.Interfaces.ISessionService
.
Infrastructure.Base.Services.SessionService
实施 Infrastructure.Base.Interfaces.ISessionService
。
Infrastructure.Base.Services.SessionService
使用 Infrastructure.Base.Interfaces.ILdapConfigService
.
Infrastructure.New.Services.LdapConfigService
实施 Infrastructure.Base.Interfaces.ILdapConfigService
.
Infrastructure.Old.Services.LdapConfigService
实施 Infrastructure.Base.Interfaces.ILdapConfigService
.
如何使用 Simple Injector
注册此逻辑。我使用了 RegisterConditional
但这不太奏效,因为 ILdapConfigService
的消费者位于 base.
container.RegisterConditional<
ILdapConfigService,
Old.Services.LdapConfigService>(
c => c.Consumer.ImplementationType.Namespace.Contains("Old"));
container.RegisterConditional<
ILdapConfigService,
New.Services.LdapConfigService>(
c => c.Consumer.ImplementationType.Namespace.Contains("New"));
container.Register<ISessionService, SessionService>();
container.Register<ILdapRepository, LdapRepository>();
每个 LdapConfigService
与一个 app.config
对话,所有重要信息都加载到其中。
Base 完成 OpenLdap
的整个实现,但 Config 需要注入 SessionService
以便它与正确的服务器通信。谁知道抽象会变得如此复杂。
我的设计模式可能有缺陷吗?
Is my design pattern perhaps flawed?
只要你确定你没有违反 Liskov 替换原则,我就找不到它的任何缺陷,尽管这种设计确实让配置容器变得有点困难。
我认为这里的技巧是创建两个 ISessionService
实现;一个用于 New
东西,一个用于 Old
东西。这使您可以根据类型进行区分。这是必需的,因为 Simple Injector 的 RegisterConditional
有限制,只允许您查看注册的直接消费者类型。您正在有条件地注册 ILdapConfigService
,但它总是被注入 SessionService
。通过为每个 ILdpConfigService
提供自己的 ISessionService
,您可以根据 ISessionSerice
.
Simple Injector 的这种限制是故意的,存在是为了防止用户进行无效配置。例如,如果SessionService
被注册为单例,它不可能有两个不同的ILdapConfigServices
。
由于创建两个 ISessionService
实现是一个 'configuration trick',您可以简单地将第二个实现定义为组合根的一部分并从第一个实现继承。通过这样做,您可以根据类型进行匹配,如下所示:
class NewSessionService : SessionService {
public NewSessionService(ILdabConfigService s) { ... }
}
container.RegisterConditional<ISessionService, SessionService>(
c => c.Consumer.ImplementationType.Namespace.Contains("Old"));
container.RegisterConditional<ILdabConfigServices, Old.LdapConfigService>(
c => c.Consumer.ImplementationType == typeof(SessionService));
container.RegisterConditional<ISessionService, NewSessionService>(
c => c.Consumer.ImplementationType.Namespace.Contains("New"));
container.RegisterConditional<ILdabConfigServices, New.LdapConfigService>(
c => c.Consumer.ImplementationType == typeof(NewSessionService));