Asp.net mvc 带构造函数注入和MEF的Asp.net MVC基本控制器
我有一个基本控制器类,它向它的子类公开一些日志功能。此日志依赖项是构造函数注入的。为了提供一些简化的代码,以下是所有代码的外观:Asp.net mvc 带构造函数注入和MEF的Asp.net MVC基本控制器,asp.net-mvc,dependency-injection,mef,constructor-injection,Asp.net Mvc,Dependency Injection,Mef,Constructor Injection,我有一个基本控制器类,它向它的子类公开一些日志功能。此日志依赖项是构造函数注入的。为了提供一些简化的代码,以下是所有代码的外观: public abstract class LogControllerBase : Controller { private readonly ILogger logger = null; protected LogControllerBase(ILogger logger) { this.logger = logger;
public abstract class LogControllerBase : Controller
{
private readonly ILogger logger = null;
protected LogControllerBase(ILogger logger)
{
this.logger = logger;
}
}
我的子控制器也有自己的依赖项,因此它们看起来像这样:
public class SomeController : LogControllerBase
{
private readonly IService service = null;
[ImportingConstructor]
public SomeController(ILogger logger, IService service)
: base(logger)
{
this.service = service;
}
}
我在单元测试中使用这些构造函数使依赖注入变得容易,但在生产中,所有的组合都是(应该)由MEF完成的。我正在使用自定义控制器工厂类,该类使用MEF来实例化控制器
总之:
InheritedExport
,并且还具有具体的实现,因此它应该按预期工作
不同的工作方案
当我尝试另一种方法,直接在那些私有字段上进行导入时,一切似乎都很好
public abstract class LogControllerBase : ControllerBase
{
[Import]
private ILogger logger = null;
protected LogControllerBase() { }
}
public class SomeController : LogControllerBase
{
[Import]
private IService service = null;
public SomeController() { }
}
这是可行的,但不一样。。。我可以在这里为依赖项注入添加构造函数,但是我有两组构造函数,在进行单元测试时,可能会使用无参数构造函数,这当然是错误的,因为不会设置依赖项。不是真的,也不是嘲笑
问题:
我如何说服MEF通过在构造函数中注入具体实现来创建控制器,方法是将依赖项注入构造函数设置为
ImportingConstructor
?这可能与线程有关,因为MEF容器在默认情况下不是线程安全的。在容器的构造函数中,尝试启用线程安全:
var container = new CompositionContainer(catalog, true);
@史蒂文:不幸的是,这是不可能的,因为MEF是由更高的库设置的内部策略,必须在我的web应用程序中使用。说实话,考虑到与此应用程序相关的其他要求,我也会选择MEF。使用其他静态定义的DI容器还不容易实现它的其他好处,我真的无法想象使用其他容器不能实现多少好处。事实上,几乎所有其他容器都更快、功能更丰富。我认为MEF唯一的亮点是处理插件架构,插件在不同的应用程序域中运行(就像VS一样)。@DarinDimitrov:不行,因为我必须使用的库使用MEF。所以这不是一个真正的解决方案。这可能是一个健康的建议,但我不能接受。不管怎样,谢谢你,达林。我很明白这一点。这就是为什么我没有把它作为答案贴出来。对于你来说,与你所在公司负责做出这些设计决策的人交谈更像是一种煽动。谁知道呢,他们甚至可能会听你说:-)AFAIK MEF插件运行在同一个AppDomain中。如果VS插件在不同的AppDomain中运行,那么这不是MEF的特性。我认为MAF是进行AppDomain分离的一个。我可以在库中看到我必须使用的语句。它使用
false
表示isThreadSafe
。那么我现在能做什么呢?您不能将isThreadSafe
设置为true
重新编译库吗?如果不是,我会向图书馆的作者提出这个问题。