gpt4 book ai didi

c# - 将不同的实现注入(inject)同一接口(interface),然后在正确的项目/程序集中选择正确的实现

转载 作者:太空宇宙 更新时间:2023-11-03 21:18:27 24 4
gpt4 key购买 nike

我们有 2 个 OpenLdap 服务器。一个是最新的开箱即用版本。另一个是较旧的高度定制版本。

这两种实现实际上都遵循相似的逻辑。以连接为例。

这是界面

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

每个实现都将使用此接口(interface)来获取连接。

新服务器

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

旧服务器

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

每个实现都在不同的项目中。每个项目都会有一个不同的 app.config 以及正确的凭据等。除此之外还有一个 IConfigService 它将所有凭据等从 app.config.

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

同样,每个项目都会有自己的实现。

由于我们在每个服务器中访问数据的方式不同,每个项目中的存储库都会不同。旧服务器将仅用于查询,因此我们使用它来将用户导入新服务器。

我将如何使用 Simple Injector 将这些服务注入(inject)到同一个接口(interface)中,但取决于使用的是哪个存储库,将引入正确的实现?这是否有意义?

  • Infrastructure.OldLdap.SomeRepo 使用Interfaces.ISessionService注册到OldLdap.Service.SessionService
  • Infrastructure.NewLdap.SomeOtherRepo 使用Interfaces.ISessionService注册到NewLdap.Service.SessionService

这是否可能,这是否也违反了 Liskov 替换原则

我是否最好将每个实现都写成自己的东西?如果是这样,这是否会破坏 DRY 原则?

希望这不会太宽泛,提前谢谢你。

最佳答案

Also does this break the Liskov Substitution Principle.

是否破坏 LSP 取决于 SessionService 类的行为方式。你应该经常问自己:“如果我交换实现会发生什么?”如果将 Oldldap 注入(inject)到 NewRepo 导致 NewRepo 在运行时失败,那么您违反了 LSP,这基本上是在告诉您您的设计是错误的。另一方面,如果 NewRepo 继续正常运行,因为 OldldapNewldap 在契约(Contract)上的行为相同,那么您就没事了。那么存储库是否关心它的实现,或者只有你关心。请注意,如果 OldldapNewRepo 的执行速度太慢,这可能不会违反 LSP。在那种情况下,只有您关心(或者可能是您的客户,因为非功能性需求)。

解决 LSP 违规的方法总是很简单:为每个实现提供自己的接口(interface)。开发人员往往对此有疑问,因为两个抽象似乎彼此完全相同,而制作“副本”似乎违反了 DRY。但是外表是骗人的;尽管他们有相同的成员,但他们有不同的、不相容的契约。

但如果您没有违反 LSP,则保留该单一接口(interface)就可以了(根据 LSP)。您可以使用 RegisterConditional 使用 Simple Injector 3 进行多个上下文注册,如下所示:

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

关于c# - 将不同的实现注入(inject)同一接口(interface),然后在正确的项目/程序集中选择正确的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32492392/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com