Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何基于最顶层父命名空间注册服务条件_C#_Design Patterns_Interface_Inversion Of Control_Simple Injector - Fatal编程技术网

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));

So
New.SomeService
应该间接使用
New.ldapconfig服务
Old.SomeOtherService
应该间接使用
Old.ldapconfig服务
是的,您是正确的,因为每个配置服务都在一个独特的项目上谢谢。我认为这种方法将是最简单的注册方法。然而,我确实在我的设计中发现了一个巨大的缺陷,类库无法读取它们各自的App.config文件,因此我不得不将所有内容都放回一个项目中。我会把我的答案贴出来,但你的答案同样有效。