简体   繁体   English

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

[英]resolving instance of class inside of method using autofac

Using this PipelineX class below, is there any way to resolve the filters applied to the pipline without injecting the autofac container and calling _container.Resolve(); 使用下面的这个PipelineX类,有没有办法解决应用于pipline的过滤器而不注入autofac容器并调用_container.Resolve();

 public class PipelineX<T> : FilterBase<T>, IPipelineX<T>
{
    private readonly IContainer _container;

    public PipelineX(IContainer container)
    {
        _container = container;
    }
    protected override T Process(T input)
    {
        return input;
    }

    public PipelineX<T> FilterBy<X>()
    {
        var filter = _container.Resolve(typeof(X)) as IFilter<T>;
        Register(filter);
        return this;
    }                             
}

To avoid the usage of Autofac as a service locator you can register your own factory method into it, in this case: 为避免将Autofac用作服务定位器,您可以在其中注册自己的工厂方法,在这种情况下:

builder.Register<Func<Type, object>>((c, p) =>
{
    var context = c.Resolve<IComponentContext>();
    return type => context.Resolve(type);
});

and use that in your PipelineX class like this: 并在您的PipelineX类中使用它,如下所示:

private readonly Func<Type, object> filterFactory;

public PipelineX(Func<Type, object> filterFactory)
{
    this.filterFactory = filterFactory;
}

protected override T Process(T input)
{
    return input;
}

public PipelineX<T> FilterBy<X>()
{
    var filter = this.filterFactory(typeof(X)) as IFilter<T>;
    Register(filter);
    return this;
}

Consider: This only removes the hard reference to the Autofac container, it's still using an abstract object factory which is not self explanatory enough and should be replaced by a custom filter factory or selector implementation. 考虑:这只删除了对Autofac容器的硬引用,它仍然使用一个抽象对象工厂,它不够自我解释,应该由自定义过滤器工厂或选择器实现替换。

This is similar to Péter's answer but uses a custom factory: 这与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;
    }
}

PipelineX implementation would be: 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;
    }
}

Registering the factory using Autofac: 使用Autofac注册工厂:

builder.Register<FilterFactory>(c =>
{
    var context = c.Resolve<IComponentContext>();
    return new FilterFactory(context.Resolve);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM