Autofac.如何在构造函数中注入一个开放的Generic代理

hus*_*ler 3 c# generics dependency-injection autofac

我试图通过像这样的构造函数注入一个开放泛型的委托

protected AQuery(Func<string, IQuery<T>> getQuery)
{
    query = getQuery("contextName");
}
Run Code Online (Sandbox Code Playgroud)

并注册类似的东西

builder
   .Register<Func<string, IQuery<T>>>(
       c => ctx => 
       new Query(c.ResolveNamed<IDbContext>(ctx)));
Run Code Online (Sandbox Code Playgroud)

我找不到任何这样的API帮助文档.

我能够使用类似的注册,其中不涉及泛型.

Ste*_*ven 10

您正在尝试实现的功能似乎是一种非常实用的方法,在F#等函数式语言中运行良好,但.NET的大多数DI容器都是针对面向对象的语言构建的,它们本质上是面向类型的,而不是委托或面向函数.您要做的事情,使用Autofac或任何其他DI容器无法轻松完成.

即使Autofac能够将泛型方法映射到Func委托,您仍然需要相当多的反射来注册它.例如这个假设的RegisterGenericFunc方法:

builder.RegisterGenericFunc(
    typeof(Func<,>).MakeGenericType(typeof(string), typeof(IQuery<>)),
    typeof(Bootstrapper).GetMethod("QueryFuncFactory"));

public static Func<string, IQuery<T>> QueryFuncFactory<T>(IComponentContext c) {
    return ctx => new Query(c.ResolveNamed<IDbContext>(ctx)));
}
Run Code Online (Sandbox Code Playgroud)

为了使其工作,Autofac不仅必须能够与代理一起工作,而且还能够理解部分开放泛型类型(您Func<string, IQuery<T>>的部分开放式通用).

因此,您可能希望回到更面向对象的方法,并定义一个描述您的抽象的清晰界面,而不是这样做:

public interface IQueryFactory<T> {
     IQuery<T> CreateQuery(string context);
}
Run Code Online (Sandbox Code Playgroud)

您的实现可能如下所示:

public class AutofacQueryFactory<T> : IQueryFactory<T> {
     private readonly IComponentContext c;

     public AutofacQueryFactory(IComponentContext c) {
         this.c= c;
     }

     public IQuery<T> CreateQuery(string context) {
         return new Query<T>(c.ResolveNamed<IDbContext>(context));
     }
}
Run Code Online (Sandbox Code Playgroud)

此接口实现对可以注册如下:

build.RegisterGeneric(typeof(AutofacQueryFactory<>)).As(typeof(IQueryFactory<>);
Run Code Online (Sandbox Code Playgroud)

您的消费者可以依赖IQueryFactory<T>:

protected AQuery(IQueryFactory<T> getQuery)
{
    query = getQuery.CreateQuery("contextName");
}
Run Code Online (Sandbox Code Playgroud)

  • 很老的答案,但仍然在"autofac + delegate"的搜索引擎顶部列表,所以认为为了完整性我应该添加更多的信息.至少目前的AutoFac版本支持[Delegate Factories](http://docs.autofac.org/en/latest/advanced/delegate-factories.html),它为开箱即用的问题提供支持. (2认同)