具有逆变类型参数和 Unity 容器的泛型
Posted
技术标签:
【中文标题】具有逆变类型参数和 Unity 容器的泛型【英文标题】:Generics with contravariant type parameters and Unity container 【发布时间】:2013-05-19 07:06:50 【问题描述】:我有一个带逆变类型参数的接口,比如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);
我只想注册基本映射器(其中TSource
是IEnumerable<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# 的方法感兴趣...
【问题讨论】:
也许更好的方法是实现一个注册 BuilderStrategy 的 Unity 扩展。 切换到不同的框架? 你为什么要尝试解析 IFooIEventHandler<TEvent>
或在使用版本化消息进行消息传递以实现向后兼容性时,会想到处理业务事件。
【参考方案1】:
听起来您每次都想解析同一个 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
的不同实现,那就另当别论了。在这种情况下,您必须注册每个实现。
【讨论】:
以上是关于具有逆变类型参数和 Unity 容器的泛型的主要内容,如果未能解决你的问题,请参考以下文章
GetMethod 的 Type[] 以获取具有两个参数和一个类型参数的泛型方法
TypeScript 中具有泛型类型参数的泛型类型的替代方案
建造者模式-具有递归类型参数的泛型类型(Effective-Java)
在具有泛型参数的泛型方法中使用 Spring RestTemplate
Kotlin泛型总结 ★ ( 泛型类 | 泛型参数 | 泛型函数 | 多泛型参数 | 泛型类型约束 | 可变参数结合泛型 | out 协变 | in 逆变 | reified 检查泛型参数类型 )