我有以下情况,实现我的接口的类需要多个泛型,但在接口的实现中只使用其中一个(另一个是关闭的)....
public interface ITest<T, TU>
{
}
public class Test<T, TU> : ITest<Guid, T>
{
}
我已尝试将其注册为
builder.RegisterGeneric(typeof (Test<,>)).AsImplementedInterfaces();
和
builder.RegisterGeneric(typeof (Test<,>)).As(typeof (ITest<,>));
但当我尝试解决时
container.Resolve<ITest<Guid, string>>();
我得到了
请求的服务'ITest`2 [[System.Guid,mscorlib, 版本= 4.0.0.0,文化=中立, PublicKeyToken = b77a5c561934e089],[System.String,mscorlib, Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]' 尚未注册。要避免此异常,请注册a 组件提供服务,检查服务注册使用 IsRegistered(),或使用ResolveOptional()方法来解析 可选的依赖。
我猜它假设泛型在实现和接口中属于同一类型?有什么建议吗?
由于
答案 0 :(得分:2)
问题是由TU
中的通用参数Test<T, TU>
引起的。请理解,此TU
与TU
中定义的ITest<TU, T>
参数无关,但这是一个完全不同的参数。为了使这一点更加明显,您应该重命名该参数,例如:
public class Test<T, X> : ITest<Guid, T>
{
}
由于此通用参数不同且未映射到ITest<TU, T>
抽象中的通用参数,因此Autofac无法从请求的X
封闭版本推断ITest<TU, T>
。问问自己:如果我要求X
,ITest<Guid, string>
应该是什么。这将解析为Test<string, X>
,但X
仍未知。
由于Autofac无法推断X
,因此永远无法使用Test<T, X>
,请求将失败。
由于Test<T, X>
永远无法解决,因此很遗憾Autofac在调用RegisterGeneric
期间没有抛出异常,因为它应该能够找出Test<T, X>
永远不会解决。
所以真正的问题是,当X
得到解决时,您希望ITest<Guid, T>
是什么? Autofac不允许部分泛型类型定义,但C#编译器也不允许,因此这通常不是问题。最简单的方法是填写&#39; X
参数来自Test<T, X>
:
// Part of your Composition Root
internal class FloatTest<T> : Test<T, float>
{
}
这个课程可以毫无问题地注册:
builder.RegisterGeneric(typeof(FloatTest<>))
.As(typeof(ITest<,>))