C# 如何在简单注入器中组合开放式通用注册和部分封闭式通用注册

C# 如何在简单注入器中组合开放式通用注册和部分封闭式通用注册,c#,dependency-injection,ioc-container,simple-injector,C#,Dependency Injection,Ioc Container,Simple Injector,我有以下接口 public interface IMapper<in TSource, out TDestination> { TDestination Map(TSource source); } 公共接口IMapper { t目标图(t来源); } 使用默认(回退)实现: public class DefaultMapper<TSource, TDestination> : IMapper<TSource, TDestination> {

我有以下接口

public interface IMapper<in TSource, out TDestination>
{
    TDestination Map(TSource source);
}
公共接口IMapper
{
t目标图(t来源);
}
使用默认(回退)实现:

public class DefaultMapper<TSource, TDestination> : IMapper<TSource, TDestination>
{
   ...
}
public类DefaultMapper:IMapper
{
...
}
并已在Simple Injector中登记如下:

container.Register(typeof(IMapper<,>), MapperAssemblies);
container.RegisterConditional(typeof(IMapper<,>), typeof(DefaultMapper<,>),
    Lifestyle.Singleton,
    c => !c.Handled);
container.Register(typeof(IMapper)、mapper组件);
container.registerCondition(typeof(IMapper)、typeof(DefaultMapper),
生活方式,单身,
c=>!c.Handled);
这允许我为特定情况编写特定的映射程序,并且每当缺少显式注册(在MapperAssemblies中)时,就会从容器返回DefaultMapper实例。太好了

然而,映射集合或其他开放泛型类中存在大量重叠。我希望避免为从一个集合到另一个集合的每个映射编写单独的实现。如何设置/调整代码并进行注册,使Simple Injector返回:

IMapper<List<TSource>, List<TDestination>> 
IMapper

IMapper

应要求。我曾尝试应用部分关闭的注册(根据文档),这适用于某些场景,但我丢失了泛型类型,这使得映射更加困难。

使用Simple Injector,这将是定义一个泛型映射器实现的问题,该实现允许从源列表映射到目标列表,像这样:

公共类列表映射器
:IMapper
{
专用只读IMapper映射器;
public ListMapper(IMapper mapper)=>this.mapper=mapper;
公共列表映射(列表源)=>
source.Select(this.mapper.Map).ToList();
}
您可以按如下方式注册此映射器:

container.Register(typeof(IMapper)、mapper组件);
Register(typeof(IMapper),typeof(ListMapper));
//最后登记
container.registerCondition(typeof(IMapper)、typeof(DefaultMapper),
生活方式,单身,
c=>!c.Handled);
注意
ListMapper
如何实现
IMapper
?这与具有泛型类型约束的效果相同,它允许Simple Injector有条件地应用映射器

如果您真的想变得有趣,并且希望能够将任何任意集合类型映射到任何其他任意集合类型,则可以定义以下通用映射器:

公共类EnumerableMapper
:IMapper
其中TInCollection:IEnumerable
where-TOutCollection:IEnumerable,new()
{
专用只读IMapper映射器;
公共EnumerableMapper(IMapper映射器)=>this.mapper=mapper;
公共TOutCollection地图(TInCollection源)=>。。。;
}
即使这个类在
IMapper
抽象之上包含两个额外的泛型类型,Simple Injector仍然能够找出所有类型应该是什么。您可以按如下方式注册此类型:

container.Register(typeof(IMapper),typeof(enumerableapper));

唯一困难的部分是正确实现它的
Map
方法,这可能会让人望而生畏,因为返回类型可以是实现
IEnumerable
的任何东西,而您应该仍然能够创建它。

太棒了!再次感谢:-)
IMapper<Source<T>, Destination<T>>