C# 使用autofac解析方法内部的类实例
使用下面的PipelineX类,是否有任何方法可以在不注入autofac容器并调用_container.resolve()的情况下解析应用于管道的过滤器C# 使用autofac解析方法内部的类实例,c#,autofac,C#,Autofac,使用下面的PipelineX类,是否有任何方法可以在不注入autofac容器并调用_container.resolve()的情况下解析应用于管道的过滤器 public class PipelineX:FilterBase,IPipelineX { 专用只读IContainer\u容器; 公用管道X(IContainer容器) { _容器=容器; } 受保护的覆盖T进程(T输入) { 返回输入; } 公共管道X过滤器比() { var filter=_container.Resolve(typeo
public class PipelineX:FilterBase,IPipelineX
{
专用只读IContainer\u容器;
公用管道X(IContainer容器)
{
_容器=容器;
}
受保护的覆盖T进程(T输入)
{
返回输入;
}
公共管道X过滤器比()
{
var filter=_container.Resolve(typeof(X))作为IFilter;
寄存器(过滤器);
归还这个;
}
}
为了避免使用Autofac作为服务定位器,您可以在其中注册自己的工厂方法,在这种情况下:
builder.Register<Func<Type, object>>((c, p) =>
{
var context = c.Resolve<IComponentContext>();
return type => context.Resolve(type);
});
考虑:这只删除了对Autofac容器的硬引用,它仍然使用一个抽象对象工厂,该工厂不够自解释,应该由一个自定义过滤器工厂或选择器实现来代替。这与péter的答案类似,但使用了一个自定义工厂:
public class FilterFactory
{
private readonly Func<Type, object> _factoryFunc;
public FilterFactory(Func<Type, object> factoryFunc)
{
_factoryFunc = factoryFunc ?? throw new ArgumentNullException(nameof(factoryFunc));
}
public IFilter<T> Create<X, T>()
{
IFilter<T> filter = Create<T>(typeof(X));
return filter;
}
public IFilter<T> Create<T>(Type type)
{
var filter = _factoryFunc(type) as IFilter<T>;
if (filter == null)
{
throw new ArgumentException($"Could not find filter for type '{type.FullName}'");
}
return filter;
}
}
公共类过滤器工厂
{
私有只读函数(factoryFunc);
公共过滤器工厂(Func工厂Func)
{
_factoryFunc=factoryFunc??抛出新的ArgumentNullException(nameof(factoryFunc));
}
公共IFilter创建()
{
IFilter filter=Create(typeof(X));
回流过滤器;
}
公共IFilter创建(类型)
{
变量过滤器=_factoryFunc(类型)作为IFilter;
if(filter==null)
{
抛出新ArgumentException($“找不到类型“{type.FullName}”的筛选器);
}
回流过滤器;
}
}
PipelineX的实施将是:
public class PipelineX<T> : FilterBase<T>, IPipelineX<T>
{
private readonly FilterFactory _factory;
public PipelineX(FilterFactory factory)
{
_factory = factory;
}
protected override T Process(T input)
{
return input;
}
public PipelineX<T> FilterBy<X>()
{
var filter = _factory.Create<X,T>() as IFilter<T>;
Register(filter);
return this;
}
}
public class PipelineX:FilterBase,IPipelineX
{
私人只读过滤器工厂;
公用管道X(过滤器工厂)
{
_工厂=工厂;
}
受保护的覆盖T进程(T输入)
{
返回输入;
}
公共管道X过滤器比()
{
var filter=_factory.Create()作为IFilter;
寄存器(过滤器);
归还这个;
}
}
使用Autofac注册工厂:
builder.Register<FilterFactory>(c =>
{
var context = c.Resolve<IComponentContext>();
return new FilterFactory(context.Resolve);
});
builder.Register(c=>
{
var context=c.Resolve();
返回新的FilterFactory(context.Resolve);
});
您可以将IEnumerable注入构造函数。您可以传递负责创建/解析IFilter
实例的factory对象,而不是将容器传递给PipelineX
类,假设有100种类型实现了IFilter
。OPs当前代码将仅实例化其中一个。我怀疑你的代码@MuratTüfekçI会实例化所有100个。有没有办法避免这种情况?您当前如何将IFilter注册到autofac?这通常被称为,相反,您应该知道如何传递到类的构造函数中,以便为此类服务注入适当的工厂或提供程序。一些服务容器甚至可以注册开放泛型,在这种情况下,您甚至可以在IFilter
上获取依赖项(在构造函数中)。但是,我不知道AutoFac,所以我不知道如何或是否可以做到这一点。
public class PipelineX<T> : FilterBase<T>, IPipelineX<T>
{
private readonly FilterFactory _factory;
public PipelineX(FilterFactory factory)
{
_factory = factory;
}
protected override T Process(T input)
{
return input;
}
public PipelineX<T> FilterBy<X>()
{
var filter = _factory.Create<X,T>() as IFilter<T>;
Register(filter);
return this;
}
}
builder.Register<FilterFactory>(c =>
{
var context = c.Resolve<IComponentContext>();
return new FilterFactory(context.Resolve);
});