我在项目中使用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>();
是否有人知道是否可以通过类型??
使委托与参数匹配答案 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将引发异常。防爆。 Component
对Dependency
异常看起来像这样:
输入参数类型列表 有重复的类型。尝试注册自定义委托类型而不是 使用通用的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);