0

我有一个 MVC3 Web 应用程序,其中控制器使用服务来执行某些任务。我用来分别实例化每个操作中所需的服务,例如:

 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.Compose(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 倍。有谁知道为什么这么慢?我做错了什么?

4

3 回答 3

1

我怀疑这是因为每个控制器实例都在重建一个 CompositionContainer,它看起来像是在进行一些磁盘访问。

您可以将 CompositionContainer 初始化移动到 Application_Start 中吗?

于 2012-07-24T14:51:26.597 回答
1

我并没有真正使用 MEF,但我认为您的解决方案会扫描 bin 文件夹中的每个程序集以搜索导入/导出属性并编写应用程序。

我认为这不是使用 MEF 的正确方法,控制器不应调用任何与 MEF 相关的方法。

如果您为每个请求配置一个 DI 容器,这似乎是相似的。

这篇文章似乎不错:Using MEF 2 with ASP.NET MVC 3

于 2012-07-24T14:55:16.213 回答
1

启动 aCompositionContainer不是一项资源密集型任务,但是,创建 a DirectoryCatalogis,它必须扫描所有可用的组件以识别零件并分析导出的组成元素。您可以通过多种方式对此进行改进:

  1. 您可以拥有所有容器在构建时使用的单数DirectoryCatalog(或者最好是 a ComposablePartCatalog),这意味着目录创建只完成一次。
  2. 您可以完全避免在构造函数中创建容器,并使用 MVC3 的内置服务定位机制实现IControllerFactory启动控制器实例或处理依赖关系解析。IDependencyResolver如果你搜索 MEF + MVC,网上有很多例子。
于 2012-07-25T09:05:42.310 回答