繁体   English   中英

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

[英]Generics with contravariant type parameters and Unity container

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

interface IFoo<in T> {}

现在我有三个班:

class B {}

class D : B {}

class Foo : IFoo<B> {}

如果我这样注册他们

container.RegisterType<IFoo<B>, Foo>();

...然后尝试解决IFoo<D> ,它失败了因为我没有真正注册IFoo<D>IFoo<> 很明显。

我当前的解决方案是迭代Registrations ,找到RegisteredType可以从解析类型(在我的情况下为IFoo<D> )分配的注册,然后解析它的MappedToType类型。

问题很简单:有更好的方法吗? 任何意见,将不胜感激。

谢谢。

编辑:

多一点背景。

我有一些映射器。

IMapper<in TSource, in TDest> : IMapper // IMapper is non-generic
{
    void Map(TSource source, TDest dest);
}

我想只注册基本映射器(其中TSourceIEnumerable<T> ),并且能够为实现IEnumerable<T>每个类型解析此映射器,例如对于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);

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

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

我会尝试使用非通用IEnumerable()而不是IEnumerable<T>container.RegisterType<IFoo<IEnumerable>, Foo>(); )来注册映射器。 如果我没记错的话,可以将通用的IEnumerable<T>传递给非通用的IEnumerable()参数,因此您不必担心传递的是哪个类型参数。 因此,当您去解决映射器时,您甚至不需要检查类型,只需解析IMapper<IEnumerable>

编译以下代码:

[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 { }

如果您需要获得不同的IMapper实现,那么这是另一个故事。 在这种情况下,您必须注册每个实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM