使用Autofac注册部分开放泛型

时间:2013-07-02 22:12:19

标签: generics autofac

我有以下情况,实现我的接口的类需要多个泛型,但在接口的实现中只使用其中一个(另一个是关闭的)....

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()方法来解析   可选的依赖。

我猜它假设泛型在实现和接口中属于同一类型?有什么建议吗?

由于

1 个答案:

答案 0 :(得分:2)

问题是由TU中的通用参数Test<T, TU>引起的。请理解,此TUTU中定义的ITest<TU, T>参数无关,但这是一个完全不同的参数。为了使这一点更加明显,您应该重命名该参数,例如:

public class Test<T, X> : ITest<Guid, T>
{
}

由于此通用参数不同且未映射到ITest<TU, T>抽象中的通用参数,因此Autofac无法从请求的X封闭版本推断ITest<TU, T>。问问自己:如果我要求XITest<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<,>))