C# 如何基于最顶层父命名空间注册服务条件
使用C# 如何基于最顶层父命名空间注册服务条件,c#,design-patterns,interface,inversion-of-control,simple-injector,C#,Design Patterns,Interface,Inversion Of Control,Simple Injector,使用SimpleInjector解决以下类时遇到问题 配置接口 Namespace Infrastructure.Base.Interfaces public interface ILdapConfigService { ..... } Namespace Infrastructure.Base.Interfaces public interface ISessionService { LdapConnection GetConnection(); } 会话接口 Na
SimpleInjector
解决以下类时遇到问题
配置接口
Namespace Infrastructure.Base.Interfaces
public interface ILdapConfigService
{
.....
}
Namespace Infrastructure.Base.Interfaces
public interface ISessionService
{
LdapConnection GetConnection();
}
会话接口
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
witch实现ILdapConfigService
不同的项目将有服务,这些服务也使用基类中的存储库
我需要知道如何注册这些接口,或者可以这样注册吗
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
如何将此逻辑注册到简单喷油器
。我使用了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>();
container.register条件<
ILdapConfigService,
Old.Services.ldapconfig服务>(
c=>c.Consumer.ImplementationType.Namespace.Contains(“旧”);
容器注册表条件<
ILdapConfigService,
新建.Services.ldapconfig服务>(
c=>c.Consumer.ImplementationType.Namespace.Contains(“New”);
container.Register();
container.Register();
每个ldapconfig服务
都与一个app.config
对话,其中所有重要信息都加载到该服务中
Base对OpenLdap
执行整个实现,但需要将配置注入到SessionService
中,以便与正确的服务器对话。谁知道抽象会变得如此复杂
我的设计模式可能有缺陷吗
我的设计模式可能有缺陷吗
只要您确定没有违反Liskov替换原则,我就找不到任何缺陷,尽管这种设计确实使容器的配置变得有点困难
我认为这里的诀窍是创建两个ISessionService
实现;一个是新的,一个是旧的。这允许您根据类型进行区分。这是必需的,因为Simple Injector的RegisterConditional
具有仅允许查看注册的直接消费者类型的限制。您正在有条件地注册ILdapConfigService
,但它总是被注入SessionService
。通过为每个ILdpConfigService
提供其自己的ISessionService
,您可以基于ISessionSerice
的使用者设置条件
简单喷油器的这一限制是故意的,旨在防止用户进行无效配置。例如,如果SessionService
注册为singleton,则它不可能有两个不同的ILdapConfigServices
由于创建两个ISessionService实现是一个“配置技巧”,您可以简单地将第二个实现定义为组合根的一部分,并从第一个实现继承它。通过这样做,您可以根据类型进行匹配,如下所示:
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));
classnewsessionservice:SessionService{
公共新闻会话服务(ILdabConfigService){…}
}
容器注册表条件(
c=>c.Consumer.ImplementationType.Namespace.Contains(“旧”);
容器注册表条件(
c=>c.Consumer.ImplementationType==typeof(SessionService));
容器注册表条件(
c=>c.Consumer.ImplementationType.Namespace.Contains(“New”);
容器注册表条件(
c=>c.Consumer.ImplementationType==typeof(NewSessionService));
SoNew.SomeService
应该间接使用New.ldapconfig服务
和Old.SomeOtherService
应该间接使用Old.ldapconfig服务
是的,您是正确的,因为每个配置服务都在一个独特的项目上谢谢。我认为这种方法将是最简单的注册方法。然而,我确实在我的设计中发现了一个巨大的缺陷,类库无法读取它们各自的App.config文件,因此我不得不将所有内容都放回一个项目中。我会把我的答案贴出来,但你的答案同样有效。