简体   繁体   English

将不同的实现注入相同的接口,然后在正确的项目/程序集中选择正确的实现

[英]Inject different implementations into same interface then pick up right implementation in right project / assembly

We have 2 OpenLdap servers. 我们有2个OpenLdap服务器。 One is the latest out of the box version. 一个是最新的开箱即用版本。 The other one is an older heavily customized version. 另一个是较旧的高度定制版本。

Both implementations really follows a similar logic. 两种实现确实遵循相似的逻辑。 Take the connection for example. 以连接为例。

Here is the interface 这是界面

namespace Infrastructure.Interfaces
{
    public interface ISessionService
    {
        LdapConnection GetConnection();       
    }
}

Each of the implementations will make use of this interface to get a connection. 每个实现都将使用此接口来获得连接。

New Server 新服务器

namespace Infrastructure.NewLdap.Service
{
    public class SessionService : ISessionService
    {
        LdapConnection GetConnection()
        {
        .....
        }
    }
}

Old Server 旧服务器

namespace Infrastructure.OldLdap.Service
{
    public class SessionService : ISessionService
    {
        LdapConnection GetConnection()
        {
        .....
        }
    }
}

Each of the implementations are in different Projects. 每个实现都在不同的项目中。 Each project will have a different app.config with the right credentials etc. Along with this there is a IConfigService which will have all the credentials etc loaded into it from the app.config . 每个项目都有一个带有正确凭据等的不同app.config 。与此同时,还有一个IConfigService ,它将从app.config加载所有凭据等。

namespace Infrastructure.Interfaces
{
    public interface IConfigService
    {
        string ServerAddress { get; }   
        ...   
        ...   
    }
}

Again each project will have its own implementation of this. 同样,每个项目都将对此有自己的实现。

The repositories in each project will be different, because of the way we access data in each of the servers. 每个项目中的存储库都会有所不同,因为我们访问每个服务器中数据的方式不同。 The old server will be used to query only so we are using it to import users into the new server. 旧服务器将仅用于查询,因此我们正在使用它将用户导入新服务器。

How would I use Simple Injector to inject these services into the same interface but depending on which repository is used, the right implementation will be pulled in? 我将如何使用Simple Injector将这些服务注入同一接口,但是根据所使用的存储库,将引入正确的实现? If that makes sense? 那有道理吗?

  • Infrastructure.OldLdap.SomeRepo Use Interfaces.ISessionService Registered with OldLdap.Service.SessionService Infrastructure.OldLdap.SomeRepo使用Interfaces.ISessionServiceOldLdap.Service.SessionService注册
  • Infrastructure.NewLdap.SomeOtherRepo Use Interfaces.ISessionService Registered with NewLdap.Service.SessionService NewLdap.Service.SessionService注册的Infrastructure.NewLdap.SomeOtherRepo使用Interfaces.ISessionService NewLdap.Service.SessionService

Is this even possible, Also does this break the Liskov Substitution Principle . 这甚至可能,这也打破了Liskov Substitution Principle

Am I better to write each implementation as it's own thing? 因为每个实现都是我自己编写的,所以更好吗? If so, won't this break the DRY principle? 如果是这样,这不会违反DRY原则吗?

Hope this is not to broad, thank you in advance. 希望这不会广泛,在此先谢谢您。

Also does this break the Liskov Substitution Principle. 这也违反了《里斯科夫替代原则》。

Whether or not you break the LSP depends on how the SessionService classes behave. 是否断开LSP取决于SessionService类的行为。 You should always ask yourself: "What will happen if I swap the implementations?" 您应该经常问自己:“如果交换实现,将会发生什么?” If injecting the Oldldap into the NewRepo causes the NewRepo to fail at runtime, you are violating the LSP, which is basically telling you your design is wrong. 如果将Oldldap注入NewRepo导致NewRepo在运行时失败,则说明您违反了LSP,这基本上是在告诉您您的设计是错误的。 If on the other hand the NewRepo keeps functioning correctly, because both the Oldldap and Newldap behave contractually the same, you're fine. 另一方面,如果NewRepo保持正常运行,因为OldldapNewldap合同行为相同,那么您就可以了。 So does the repository care about its implementation, or do only you care. 存储库也关心它的实现,还是只关心您。 Note that if the Oldldap performs too slow for NewRepo , that is probably not a violation of LSP. 请注意,如果Oldldap执行过慢NewRepo ,这可能是不违反LSP的。 In that case only you care (or probably your customer, because of non-functional requirements). 在那种情况下,只有您在乎(或者可能是您的客户,因为非功能性要求)。

The solution to LSP violations is always quite easy: give each implementation its own interface. 违反LSP的解决方案总是很容易的:为每个实现提供自己的接口。 Developers tend to have problems with this, because both abstractions seem exact duplicates of each other and making 'a copy' seems to violate DRY. 开发人员往往对此有问题,因为两个抽象看起来都是彼此完全相同的副本,并且制作“副本”似乎违反了DRY。 But appearances are deceptive; 但是,外表是欺骗性的。 although they have the same members, they have a different, incompatible, contract. 尽管它们具有相同的成员,但是它们具有不同的,不兼容的合同。

But in case you are not violating LSP, keeping that single interface is fine (according to the LSP). 但是,如果您没有违反LSP,则保持该单一接口正常(根据LSP)。 You can make multiple contextual registrations with Simple Injector 3 using RegisterConditional as follows: 您可以使用RegisterConditional使用Simple Injector 3进行多个上下文RegisterConditional ,如下所示:

container.RegisterConditional<ISessionService,
    Infrastructure.OldLdap.Service.SessionService>(
    c => c.Consumer.ImplementationType.Namespace.Contains("Oldldap"));

container.RegisterConditional<ISessionService,
    Infrastructure.NewLdap.Service.SessionService>(
    c => c.Consumer.ImplementationType.Namespace.Contains("Newldap"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在多个构造函数参数中注入具有相同接口的不同实现 - Inject different implementations that have same interface in multiple constructor parameters 如何在没有条件/上下文DI的情况下将不同的实现注入相同的接口? - How to inject different implementations to same interface without conditional/context DI? 如何将一个接口的多个实现注入一个实现中 - How to Inject multiple Implementations of an Interface into one Implementation 以正确的方式从另一个程序集实例化接口实现 - Instantiating interface implementation from another assembly the right way 在运行时将命令的不同实现注入命令 - Inject different implementations of an Interface to a command at runtime DI:不同控制器的相同接口的不同实现 - DI: Different implementations of the same interface for the different controllers 使用ninject绑定同一接口的不同实现 - Bind different implementations of same Interface using ninject 子类继承相同接口的不同实现 - Child classes inheriting different implementations of the same interface C#接口实现:做正确的事 - C# Interface implementation: doing the right thing 如何让.NET Reflector选择正确版本的.NET编译程序集? - How to enable .NET Reflector to pick the right version of .NET compiled assembly?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM