C# 使用autofac解析方法内部的类实例

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

使用下面的PipelineX类,是否有任何方法可以在不注入autofac容器并调用_container.resolve()的情况下解析应用于管道的过滤器

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);
});