Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 带构造函数注入和MEF的Asp.net MVC基本控制器_Asp.net Mvc_Dependency Injection_Mef_Constructor Injection - Fatal编程技术网

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来实例化控制器

总之:

  • 我有一个基础抽象控制器类,它有自己的依赖项
  • 我有后代控制器,它们使用导入来获取MEF注入的参数(即它们的依赖项以及基类的依赖项)
  • 单元测试不使用MEF,所以mock被注入到构造函数参数中
  • 问题 这一切对我来说都是站得住脚的,但MEF的想法不同。当我编译并运行此代码时,会出现以下异常:

    在设置先决条件导入“SomeController..ctor(Parameter=“logger”,ContractName=“ILogger”)”之前,无法调用GetExportedValue。

    所有用作构造函数参数的接口类型都在其上设置了属性
    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
    重新编译库吗?如果不是,我会向图书馆的作者提出这个问题。