Autofac.如何在构造函数中注入打开的泛型委托
本文关键字:泛型 注入 构造函数 Autofac | 更新日期: 2023-09-27 17:51:11
我试图通过像这样的构造函数注入一个开放泛型的委托
protected AQuery(Func<string, IQuery<T>> getQuery)
{
query = getQuery("contextName");
}
和Register类似
builder
.Register<Func<string, IQuery<T>>>(
c => ctx =>
new Query(c.ResolveNamed<IDbContext>(ctx)));
我找不到任何API帮助文档。
我可以在不涉及泛型的地方使用类似的注册
你试图实现的似乎是一种非常实用的方法,在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)));
}
要实现这一点,Autofac不仅要能够处理委托,还要能够理解部分开放泛型类型(您的Func<string, IQuery<T>>
是部分开放泛型)。
因此,与其这样做,您可能想要退回到更面向对象的方法,并定义一个清晰的接口来描述您的抽象:
public interface IQueryFactory<T> {
IQuery<T> CreateQuery(string context);
}
你的实现可以像这样:
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));
}
}
接口实现对的注册方式如下:
build.RegisterGeneric(typeof(AutofacQueryFactory<>)).As(typeof(IQueryFactory<>);
你的消费者可以依靠IQueryFactory<T>
:
protected AQuery(IQueryFactory<T> getQuery)
{
query = getQuery.CreateQuery("contextName");
}