c# - 使用简单注入(inject)器解析具有相同类和接口(interface)的多个对象

标签 c# .net simple-injector

我正在尝试在我的新项目中从 Unity 迁移到 Simple Injector。它比 Unity 快得多,我必须尝试一下。我遇到过一些坎坷,但没有什么是我无法解决的。但我又用“按键查找”找到了另一个

我已阅读this简单注入(inject)器的创建者表示他相信您不需要为每个接口(interface)解析多个类。

我一定是一个糟糕的程序员,因为我已经用Unity(它支持得很好)做到了这一点,并且想在我当前的项目中做到这一点。

我的场景是我有一个 IRepository 接口(interface)。我有两个独立的存储库,我想使用 IRepository 接口(interface)进行抽象。像这样:

container.Register<FirstData>(() => new FirstData());
container.Register<IRepository>(
           () => new GenericRepository(container.GetInstance<FirstData>()));


container.Register<SecondEntities>(() => new SecondEntities());
container.Register<IRepository>(
           () => new GenericRepository(container.GetInstance<SecondData>()));

IRepository/GenericRepository 是一种相当常见的抽象,但在 SimpleInjector 中只能有一个

在 Unity 中,我可以注册两个存储库,然后设置构造函数注入(inject)来注入(inject)我需要的实例。这是使用实例的 key 来完成的。 (我不需要在正常代码中执行 Resolve 调用,也不需要在设置之外添加对 Unity 的依赖项。)

对于简单的注入(inject)器,这是行不通的。但是,无论好坏,Simple Injector 的所有者认为这个功能是一个坏主意。

注意:作者的“应用内”系统看起来使用字符串键进行查找,但每次仍然需要不同的类(DefaultRequestHandlerOrdersRequestHandlerCustomersRequestHandler)。 我只有一个GenericRepostory,它允许我抽象我的存储库方法,无论我连接到什么。

我想我每次想要实例化它时都可以继承我的GenericRepostory。或者让它采用我不需要的随机类型参数。但这扰乱了我的设计,所以我希望有另一种方法来做到这一点。

那么有没有什么解决方法可以让我不必创建虚假类型来区分我的两个 IRepository/GenericRepository 实例?

最佳答案

我们最终将通用存储库更改为如下所示:

/// The Type parameter has no funcionality within the repository, 
/// it is only there to help us differentiate when registering 
/// and resolving different repositories with Simple Injector.
public class GenericRepository<TDummyTypeForSimpleInjector> : IRepository

(我们为其添加了一个类型参数)。
然后我们创建了两个像这样的虚拟类(我更改了类的名称以匹配我的示例):

// These are just dummy classes that are used to help 
// register and resolve GenericRepositories with Simple Injector.
public class FirstDataSelector { }
public class SecondDataSelector { }

然后我可以像这样注册它们:

container.Register<FirstData>(() => new FirstData());
container.Register(() => new GenericRepository<FirstDataSelector>
                   (container.GetInstance<FirstData>()));


container.Register<SecondEntities>(() => new SecondEntities());
container.Register(() => new GenericRepository<SecondDataSelector>
                   (container.GetInstance<SecondData>()));

(请注意 GenericRepository 上的泛型类型参数,并且我没有将其注册为 IRepository。这两个更改对于完成这项工作至关重要。)

这很好用。然后我就可以在业务逻辑的构造函数注入(inject)中使用该注册。

container.Register<IFirstBusiness>(() => new FirstBusiness
               (container.GetInstance<GenericRepository<FirstDataSelector>>()));
container.Register<ISecondBusiness>(() => new SecondBusiness
               (container.GetInstance<GenericRepository<SecondDataSelector>>()));

由于我的业务类采用IRepository,它工作正常,并且不会向业务类公开 IOC 容器或我的存储库的实现。

我基本上使用 Type 参数作为查找的键。 (我知道一个技巧,但我的选择有限。)

不得不在我的设计中添加虚拟类有点令人失望,但我们的团队认为这个缺点是值得的,而不是放弃 Simple Injector 并返回到 Unity。

关于c# - 使用简单注入(inject)器解析具有相同类和接口(interface)的多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16923360/

相关文章:

java - 在这个例子中,需要拆箱时是否使用装箱?

c# - 除了ICMP(Ping)以外,如何从LAN控制计算机是否处于打开状态?

c# - 为异步方法编写包装器

c# - Windows 8 Metro 本地主机查找

c# - 在 C# 中连接到 tableau postgresql

c# - Control.Invoke 在隐藏的 ShowDialog 中获取 'stuck'

.net - 无法读取我的自定义 .config 部分

c# - RegisterCollection 来自以前使用简单注入(inject)器注册的类型

c# - 使用 Caliburn Micro 的简单注入(inject)器 GetAllInstances 抛出异常

c# - 简单注入(inject)器注入(inject) PageModel ASP.NET Core Razor 页面