Asp.net mvc 如何告诉MEF为每个应用程序的给定类型实例化单个对象?

Asp.net mvc 如何告诉MEF为每个应用程序的给定类型实例化单个对象?,asp.net-mvc,dependency-injection,singleton,mef,repository-pattern,Asp.net Mvc,Dependency Injection,Singleton,Mef,Repository Pattern,假设我有一个名为FooController的类,其中有一个名为Bar的属性,类型为IBar(interface)。我需要通过MEF初始化Bar。但是,我需要MEF在应用程序期间只创建一个IBar类型的实例(尽管由于多个请求而多次调用对其进行初始化),并使其对所有请求同时可用。注意,可以假设IBar实现是线程安全的 i、 e 问题是每次我在FooController上调用Get()时,返回的时间值都会发生变化。这意味着正在为每个调用重新实例化MyBar对象。我基本上需要它返回相同的值,这意味着我需

假设我有一个名为FooController的类,其中有一个名为Bar的属性,类型为IBar(interface)。我需要通过MEF初始化Bar。但是,我需要MEF在应用程序期间只创建一个IBar类型的实例(尽管由于多个请求而多次调用对其进行初始化),并使其对所有请求同时可用。注意,可以假设IBar实现是线程安全的

i、 e

问题是每次我在FooController上调用Get()时,返回的时间值都会发生变化。这意味着正在为每个调用重新实例化MyBar对象。我基本上需要它返回相同的值,这意味着我需要告诉MEF在我的应用程序中只创建一个IBar实例,尽管有多个请求


提前感谢。

您需要在
MyBar
导出中指定
PartCreationPolicy
属性。像这样:

[Export(typeof(IBar))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MyBar : IBar
{
    // ...
}
这也意味着您不需要在导入时指定创建策略:

[Import]
public IBar Bar { get; set; }

MEF的ASP.NET MVC集成将
CreationPolicy.Any
CreationPolicy.Shared
解释为每个HTTP请求的单个实例。您需要对部件应用
ApplicationShared
属性,以便在HTTP请求之间共享该部件

更新:

应用程序共享属性可以在
系统.ComponentModel.component.Web.Mvc
程序集中找到。不幸的是,这不是与框架4.5一起发布的。可以在lib文件夹中的示例中找到它。缺点是,您必须引用在该示例中找到的合成程序集,而不是最新的合成程序集

如果您不想这样做,那么从这个非常简单的方法开始:

  • mvcapapplication
    类中添加一个
    CompositionContainer
    ,作为
    public
    属性
  • mvcapapplication
    构造函数上创建容器并添加一些目录
  • 在控制器上,从HttpContext获取应用程序,并使用
    CompositionContainer
    GetExportedValue
    /
    GetExportedValues
    方法之一。无需在容器上调用
    ComposeParts

  • 还有很多其他更为详细的方法,但这应该让您开始。

    但这意味着我必须在静态变量中维护CompositionContainer,并每次在同一容器上调用ComposeParts()。然而,我读到MEF CompositionContainer不是线程安全的。因此,当多个线程同时调用同一容器上的ComposeParts时,我会得到一个错误。类似于“一批已经在处理中”的东西。在构造函数上使用isThreadSafe参数没有帮助。您好,谢谢您的回复,但我很难找到您建议的此ApplicationShared属性(甚至是msdn链接)的使用示例。您是否可以指定使用示例或链接?@Harindaka您可以在System.ComponentModel.Composition.Web.Mvc程序集中找到它。我发现System.ComponentModel.Composition.Web.Mvc已被弃用,可以在上找到“经典”示例。我正在使用MVC4和.NET4.0。有什么建议吗?已经有一段时间了,但如果您仍然需要它,下面讨论如何将MEF2与MVC4集成:
    [Import]
    public IBar Bar { get; set; }