C# 具有逆变类型参数和Unity容器的泛型

C# 具有逆变类型参数和Unity容器的泛型,c#,.net,generics,dependency-injection,unity-container,C#,.net,Generics,Dependency Injection,Unity Container,我有一个带有逆变类型参数的接口,比如说IFoo: interface IFoo<in T> {} 我只想注册基本映射器(其中TSource是IEnumerable),并且能够为实现IEnumerable的每种类型解析此映射器,例如T[]: object source = GetSource(); // runtime type is T[] object dest = GetDest(); Type mapperType = typeof(IMapper<,>).Ma

我有一个带有逆变类型参数的接口,比如说
IFoo

interface IFoo<in T> {}
我只想注册基本映射器(其中
TSource
IEnumerable
),并且能够为实现
IEnumerable
的每种类型解析此映射器,例如
T[]

object source = GetSource(); // runtime type is T[]
object dest = GetDest();

Type mapperType = typeof(IMapper<,>).MakeGenericType(source.GetType(), dest.GetType());
IMapper mapper = (IMapper) container.Resolve(mapperType);
mapper.Map(source, dest);
objectsource=GetSource();//运行时类型为T[]
object dest=GetDest();
类型mapperType=typeof(IMapper).MakeGenericType(source.GetType(),dest.GetType());
IMapper映射器=(IMapper)container.Resolve(mapperType);
映射器映射(源、目标);

是的,我只对基于Unity/C的方法感兴趣…

听起来你每次都想解析同一个映射器。如果这是正确的,并且IEnumerable是您的映射程序需要处理的唯一接口,那么您的方法似乎有点过头了

我将尝试使用非泛型的
IEnumerable()
,而不是
IEnumerable
container.RegisterType();
)注册映射程序。如果我没记错的话,泛型的
IEnumerable
可以传递给非泛型的
IEnumerable()
参数,所以您不必担心传递的是什么类型的参数。因此,当您要解析映射器时,甚至不需要检查类型,只需解析
IMapper

已编译以下代码:

[TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {            
            IEnumerable<int> coll = new int[0];
            IEnumerable coll2 = coll;

         var blah = new Test<IEnumerable<int>>();
    }
}

public interface ITest<in T> where T : IEnumerable
{
}

public class Test<T> : ITest<T> where T : IEnumerable { }
[TestClass]
公共类UnitTest1
{
[测试方法]
公共void TestMethod1()
{            
IEnumerable coll=新整数[0];
IEnumerable coll2=coll;
var blah=新测试();
}
}
公共接口ITest,其中T:IEnumerable
{
}
公共类测试:ITest其中T:IEnumerable{}

如果您需要获得不同的
IMapper
实现,那就另当别论了。在这种情况下,您必须注册每个实现。

也许更好的方法是实现一个Unity扩展,注册一个BuilderStrategy,这样做。切换到不同的框架?为什么您要尝试在不注册的情况下解析IFoo?注册或解析是动态的吗?@WiktorZychla:你只想注册IFoo@WiktorZychla:在某些情况下,这是有意义的(尽管很少)。但是使用
IEventHandler
或使用版本化消息进行消息传递以实现向后兼容性时,会想到如何处理业务事件。
IMapper<in TSource, in TDest> : IMapper // IMapper is non-generic
{
    void Map(TSource source, TDest dest);
}
object source = GetSource(); // runtime type is T[]
object dest = GetDest();

Type mapperType = typeof(IMapper<,>).MakeGenericType(source.GetType(), dest.GetType());
IMapper mapper = (IMapper) container.Resolve(mapperType);
mapper.Map(source, dest);
[TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {            
            IEnumerable<int> coll = new int[0];
            IEnumerable coll2 = coll;

         var blah = new Test<IEnumerable<int>>();
    }
}

public interface ITest<in T> where T : IEnumerable
{
}

public class Test<T> : ITest<T> where T : IEnumerable { }