Autofac使用委托工厂按类型解析

时间:2015-02-12 09:01:17

标签: c# dependency-injection inversion-of-control autofac

我在项目中使用Autofac for IoC。由于某些遗留软件库,我必须将一些服务传递给无法解析的控制器,并且必须作为参数传递。

我使用这样的委托工厂制作了一个通用控件:

public MyClass<TController, TInterface> {

     private delegate TController ControllerFactory(TInterface service);

     protected TController _myController;
     protected TController Controller {
         get
         {
             return _controller 
               ?? (_controller = ServiceLocator.Resolve<ControllerFactory>()
                                    .Invoke(this);
         }
     }

}

这很有效,但为了实现这一点,我需要控制器的服务参数名称和委托服务参数名称相同,因为正如我所读,Autofac将参数BY NAME配对!

我已经看到你可以通过使用通用Func&lt;&gt;注册类来完成它,但是由于遗留应用程序我需要离开&#34; clean&#34;注册即:

containerBuilder.RegisterType<MyController>();

是否有人知道是否可以通过类型??

使委托与参数匹配

2 个答案:

答案 0 :(得分:2)

  

有没有人知道是否可以通过类型??

使委托与参数匹配

是的,您可以使用预定义的委托。请参阅动态实例化部分here

这是一个简单的例子:

    public class ComponentFactory
    {
        private readonly Func<Dependency, Component> _componentFactory;

        public ComponentFactory(Func<Dependency, Component> componentFactory)
        {
            _componentFactory = componentFactory;
        }

        public Component Create(Dependency dependency)
        {
            return _componentFactory(dependency);
        }
    }

    public class Component
    {
        private readonly Dependency _dependency;

        public Component(Dependency dependency)
        {
            _dependency = dependency;
        }
    }

    public class Dependency
    {
    }

注册+使用

            var builder= new ContainerBuilder();
            builder.RegisterType<ComponentFactory>();
            builder.RegisterType<Component>();
            builder.RegisterType<Dependency>();

            var container = builder.Build();
            var factory = container.Resolve<ComponentFactory>();

            //Usage with typed parameters
            var component = factory.Create(new Dependency());

**警告,如果您使用此方法,如果您尝试添加具有相同类型的参数,Autofac将引发异常。防爆。 ComponentDependency

有两个依赖关系

异常看起来像这样:

  

输入参数类型列表   有重复的类型。尝试注册自定义委托类型而不是   使用通用的Func关系。

答案 1 :(得分:0)

Autofac比大多数DI容器更具体地说明您注册控制器的类型。如果在控制器的注册中包含.AsSelf(),它将仅按类型解析类型。这是我们在项目中用于注册MVC控制器的模块。

public class MvcModule
    : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var currentAssembly = typeof(MvcModule).Assembly;

        builder.RegisterAssemblyTypes(currentAssembly)
            .Where(t => typeof(IController).IsAssignableFrom(t))
            .AsImplementedInterfaces()
            .AsSelf()
            .InstancePerDependency();
    }
}

使用此注册,您可以按控制器类型解析每个控制器。

var type = typeof(HomeController);
var controller = container.Resolve(type);