C# 自动传真机。如何在构造函数中插入打开的泛型委托
我正试图通过这样的构造函数注入一个带有opengeneric的委托C# 自动传真机。如何在构造函数中插入打开的泛型委托,c#,generics,dependency-injection,autofac,C#,Generics,Dependency Injection,Autofac,我正试图通过这样的构造函数注入一个带有opengeneric的委托 protected AQuery(Func<string, IQuery<T>> getQuery) { query = getQuery("contextName"); } 受保护的查询(Func getQuery) { query=getQuery(“contextName”); } 然后注册类似 builder .Register<Func<string, IQuery
protected AQuery(Func<string, IQuery<T>> getQuery)
{
query = getQuery("contextName");
}
受保护的查询(Func getQuery)
{
query=getQuery(“contextName”);
}
然后注册类似
builder
.Register<Func<string, IQuery<T>>>(
c => ctx =>
new Query(c.ResolveNamed<IDbContext>(ctx)));
builder
.登记(
c=>ctx=>
新查询(c.ResolveNamed(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)));
}
builder.RegisterGenericFunc(
typeof(Func).MakeGenericType(typeof(string),typeof(IQuery)),
typeof(Bootstrapper).GetMethod(“QueryFuncFactory”);
公共静态函数QueryFuncFactory(IComponentContext c){
返回ctx=>newquery(c.ResolveNamed(ctx));
}
但是,要使其起作用,Autofac不仅必须能够处理委托,还必须能够理解部分打开的泛型类型(您的Func
是部分打开的泛型)
因此,与此相反,您可能希望退回到更面向对象的方法,并定义一个清晰的接口来描述您的抽象:
public interface IQueryFactory<T> {
IQuery<T> CreateQuery(string context);
}
公共接口工厂{
IQuery CreateQuery(字符串上下文);
}
您的实现可以如下所示:
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));
}
}
公共类AutofacQueryFactory:IQueryFactory{
私有只读IComponentContext c;
公共AutofacQueryFactory(IComponentContext c){
这个.c=c;
}
公共IQuery CreateQuery(字符串上下文){
返回新查询(c.ResolveNamed(context));
}
}
此接口实现对可以按如下方式注册:
build.RegisterGeneric(typeof(AutofacQueryFactory<>)).As(typeof(IQueryFactory<>);
build.RegisterGeneric(typeof(AutofacQueryFactory)).As(typeof(IQueryFactory);
您的消费者可以依赖于IQueryFactory
:
受保护的队列(IQueryFactory getQuery)
{
query=getQuery.CreateQuery(“contextName”);
}
谢谢Steven。我实际上是在与确认了autofac的可能性后使用这种方法的。答案很旧,但仍在搜索引擎“autofac+委派”的榜首,因此认为为了完整起见,我应该添加更多关于这方面的信息。至少当前版本的AutoFac支持,这为这个问题提供了开箱即用的支持。
protected AQuery(IQueryFactory<T> getQuery)
{
query = getQuery.CreateQuery("contextName");
}