Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# 使用Simple Injector解析具有相同类和接口的多个对象_C#_.net_Simple Injector - Fatal编程技术网

C# 使用Simple Injector解析具有相同类和接口的多个对象

C# 使用Simple Injector解析具有相同类和接口的多个对象,c#,.net,simple-injector,C#,.net,Simple Injector,在我的新项目中,我正在尝试从Unity迁移到Simple Injector。它比统一快得多,我必须试一试。我有过一些颠簸,但没有什么是我不能克服的。但我用“按键查找”打了另一个 我已经读过SimpleInjector的创建者在其中陈述他的信念,即每个接口不需要解析多个类 我必须是一个差劲的程序员,因为我已经用Unity做了这件事(Unity非常支持它),并且想在我当前的项目中做这件事 我的设想是我有一个IRepository接口。我想使用IRepository接口抽象两个独立的存储库。像这样:

在我的新项目中,我正在尝试从Unity迁移到Simple Injector。它比统一快得多,我必须试一试。我有过一些颠簸,但没有什么是我不能克服的。但我用“按键查找”打了另一个

我已经读过SimpleInjector的创建者在其中陈述他的信念,即每个接口不需要解析多个类

我必须是一个差劲的程序员,因为我已经用Unity做了这件事(Unity非常支持它),并且想在我当前的项目中做这件事

我的设想是我有一个IRepository接口。我想使用IRepository接口抽象两个独立的存储库。像这样:

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>()));
container.Register(()=>newfirstdata());
集装箱。登记(
()=>新的GenericRepository(container.GetInstance());
container.Register(()=>newsecondentities());
集装箱。登记(
()=>新的GenericRepository(container.GetInstance());
IRepository/GenericRepository是一个相当常见的抽象,但在SimpleInjector中只能有一个

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

对于简单的喷油器,这不起作用。但是,不管是好是坏,Simple Injector的所有者认为这个功能是个坏主意

注意:作者的“应用内”系统看起来像是使用字符串键进行查找,但每次都需要不同的类(
DefaultRequestHandler
OrdersRequestHandler
CustomersRequestHandler
我只有一个
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
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>()));
然后我可以这样注册它们:

/// 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
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>()));
container.Register(()=>newfirstdata());
container.Register(()=>新的GenericRepository
(container.GetInstance());
container.Register(()=>newsecondentities());
container.Register(()=>新的GenericRepository
(container.GetInstance());
(请注意GenericRepository上的泛型类型参数,我没有将其注册为IRepository。这两个更改对于实现此功能至关重要。)

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

container.Register<IFirstBusiness>(() => new FirstBusiness
               (container.GetInstance<GenericRepository<FirstDataSelector>>()));
container.Register<ISecondBusiness>(() => new SecondBusiness
               (container.GetInstance<GenericRepository<SecondDataSelector>>()));
container.Register(()=>newfirstbusiness
(container.GetInstance());
container.Register(()=>newsecondbusiness
(container.GetInstance());
由于我的业务类采用了
IRepository
,因此它工作正常,不会向业务类公开IOC容器或我的存储库的实现

我基本上使用类型参数作为查找键。(我知道,但我的选择有限。)


不得不在我的设计中添加虚拟类有点令人失望,但我们的团队认为这个缺点是值得的,而不是放弃简单的注入器并返回Unity。我们最终将通用存储库更改为这样:

/// 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
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>()));
然后我可以这样注册它们:

/// 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
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>()));
container.Register(()=>newfirstdata());
container.Register(()=>新的GenericRepository
(container.GetInstance());
container.Register(()=>newsecondentities());
container.Register(()=>新的GenericRepository
(container.GetInstance());
(请注意GenericRepository上的泛型类型参数,我没有将其注册为IRepository。这两个更改对于实现此功能至关重要。)

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

container.Register<IFirstBusiness>(() => new FirstBusiness
               (container.GetInstance<GenericRepository<FirstDataSelector>>()));
container.Register<ISecondBusiness>(() => new SecondBusiness
               (container.GetInstance<GenericRepository<SecondDataSelector>>()));
container.Register(()=>newfirstbusiness
(container.GetInstance());
container.Register(()=>newsecondbusiness
(container.GetInstance());
由于我的业务类采用了
IRepository
,因此它工作正常,不会向业务类公开IOC容器或我的存储库的实现

我基本上使用类型参数作为查找键。(我知道,但我的选择有限。)


不得不在我的设计中添加虚拟类有点令人失望,但我们的团队认为这个缺点是值得的,而不是放弃简单的注入器并返回Unity。您自己的答案实际上相当不错,但不幸的是,您将泛型类型参数视为虚拟;您应该使其成为您设计的头等公民:

public interface IRepository<TData> { }

public clss GenericRepository<TData> : IRepository<TData>
{ 
    public GenericRepository(TData data) { }
}
更进一步说,您的业务类也可能受益于泛型类型。例如,看看每个业务操作都有自己的类,但所有业务操作都隐藏在相同的泛型
ICommandHandler
抽象后面。执行此操作时,所有业务类都可以通过单个调用注册:

container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
    typeof(ICommandHandler<>).Assembly);
container.RegisterManyForOpenGeneric(typeof(ICommandHandler),
类型(ICommandHandler).Assembly);
此调用在提供的程序集中搜索
ICommandHandler
接口的实现,并注册找到的每个实现