C# MVC3中使用MEF的依赖注入似乎异常缓慢
我有一个MVC3 web应用程序,其中控制器使用服务来执行某些任务。 我使用来分别实例化每个操作中所需的服务,例如:C# MVC3中使用MEF的依赖注入似乎异常缓慢,c#,asp.net-mvc-3,dependency-injection,mef,performance,C#,Asp.net Mvc 3,Dependency Injection,Mef,Performance,我有一个MVC3 web应用程序,其中控制器使用服务来执行某些任务。 我使用来分别实例化每个操作中所需的服务,例如: public ActionResult Index() { ICustomService customService = new CustomService(); var list = customService.ReturnSomething(); ..... return View(list)
public ActionResult Index()
{
ICustomService customService = new CustomService();
var list = customService.ReturnSomething();
.....
return View(list)
}
这很好用。然后我决定使用MEF进行依赖注入,以遵循更好的设计原则。现在我在做这样的事情:
public class MyController : Controller
{
[Import]
private ICustomService _customService;
public MyController()
{
MEFManager.Compose(this);
}
public ActionResult Index()
{
var list = _customService.ReturnSomething();
return View(list);
}
其中合成由MEFManage完成。合成(this)是以下功能:
public static void Compose(object o)
{
var container = new CompositionContainer(
new DirectoryCatalog(Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "bin"))
);
var batch = new CompositionBatch();
batch.AddPart(o);
container.Compose(batch);
}
这实际上是可行的,但它比我不使用MEF时慢6到7倍。
有人知道为什么这么慢吗?我做错了什么?我怀疑这是因为每个控制器实例都在重建一个CompositionContainer,看起来它进行了一些磁盘访问
能否将CompositionContainer初始化移到Application_Start中?我怀疑这是因为每个控制器实例正在重建一个CompositionContainer,看起来它进行了一些磁盘访问
您能将CompositionContainer初始化移动到应用程序\u Start中吗?我实际上不使用MEF,但我认为您的解决方案会扫描bin文件夹中的每个程序集,以搜索导入/导出属性并编写应用程序 我认为这不是使用MEF的正确方法,控制器不应该调用任何与MEF相关的方法 如果您为每个请求配置一个DI容器,则看起来类似
这篇文章看起来不错:我并不真正使用MEF,但我认为您的解决方案会扫描bin文件夹中的每个程序集,以搜索导入/导出属性并编写应用程序 我认为这不是使用MEF的正确方法,控制器不应该调用任何与MEF相关的方法 如果您为每个请求配置一个DI容器,则看起来类似
这篇文章看起来不错:旋转一个
合成容器
不是一项资源密集型任务,但是,创建一个目录
是,它必须扫描所有可用的组件以识别零件并分析用于导出的合成元素。您可以通过多种方式对此进行改进:
DirectoryCatalog
(或者最好是一个ComposablePartCatalog
),所有容器在构造时都会使用该目录,这意味着目录创建只进行一次IControllerFactory
来加速控制器实例,或者实现idependencysolver
来使用MVC3内置的服务位置机制处理依赖项解析。如果你搜索MEF+MVC,网上有很多例子旋转一个
合成容器
不是一项资源密集型任务,但是,创建一个目录
是,它必须扫描所有可用的组件以识别零件并分析用于导出的合成元素。您可以通过多种方式对此进行改进:
DirectoryCatalog
(或者最好是一个ComposablePartCatalog
),所有容器在构造时都会使用该目录,这意味着目录创建只进行一次IControllerFactory
来加速控制器实例,或者实现idependencysolver
来使用MVC3内置的服务位置机制处理依赖项解析。如果你搜索MEF+MVC,网上有很多例子非常感谢。我试过了,但没有加快速度。正如@Matthew Abbott在他的回答中所说的,创建一个CompositionContainer并不是一项密集的任务。谢谢。我试过了,但没有加快速度。正如@Matthew Abbott在他的回答中所说的,创建一个CompositionContainer并不是一项繁重的任务。我选择了您建议的第一个解决方案,并在Application_Start中创建了一个单一的DirectoryCatalog。它又快了。非常感谢。Ps:我已经阅读了您在“fidelitydesign.net”上的文章,但未能理解它们如何帮助我解决这个问题。@Martin-这些示例使用了我在第2项(上文)中讨论的实现-这与您在项目中采用的方法不同,可能是它们没有帮助您的原因。尽管如此,您的构造函数的当前类设计确实隐藏了它的依赖项,并且类本身构成了它自己。虽然这确实有效,但更好的设计是将
iccustomservice
作为参数传递给构造函数,因为这允许API表达其依赖性需求。这将引导您使用第#2项(上面)。我选择了您建议的第一个解决方案,并在Application#u Start中创建了一个单一的DirectoryCatalog。它又快了。非常感谢。Ps:我已经阅读了您在“fidelitydesign.net”上的文章,但未能理解它们如何帮助我解决这个问题。@Martin-这些示例使用了我在第2项(上文)中讨论的实现-这与您在项目中采用的方法不同,可能是它们没有帮助您的原因。尽管如此,您的构造函数的当前类设计确实隐藏了它的依赖项,并且类本身构成了它自己。虽然这确实有效,但更好的设计是将iccustomservice
作为参数传递给构造函数,因为这允许API表达其依赖性需求。这将引导您使用第#2项(上面)。感谢您提供指向我们文章的指针。自从发布以来,我们已经经历了几次迭代(一个全新的合成引擎!),因此合成提供程序目前正在作为一个演示分发-Microsoft.composition.Demos.Web.Mvc on-而不是通过NuGet。这里有更多信息:。干杯谢谢你给我们文章的指针。自从它发布(一个全新的合成引擎!)以来,我们已经经历了几次迭代