2012-07-24 80 views
0

我有一個MVC3 Web應用程序,其中控制器使用服務來執行某些任務。 我使用單獨的實例,針對每個動作所需要的服務,像這樣的例子:MVC3中依賴注入與MEF似乎異常緩慢

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完成(這)是如下功能:

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); 
    } 

這實際工作卻是6到7比我不使用MEF時慢。 有誰知道它爲什麼這麼慢?我做錯了什麼?

回答

1

紡了CompositionContainer不是一個資源密集型任務,,創建DirectoryCatalog是,它能夠掃描所有可用的組件,以確定零件和分析的組成元素出口。你可以這樣提高了一些方法:

  1. 你可以有一個奇異DirectoryCatalog(或最好是ComposablePartCatalog),您的所有容器使用施工時,這意味着該目錄下建立只進行一次。
  2. 您可以完全避免在構造函數中創建容器,並實現一個IControllerFactory來啓動您的控制器實例,或者使用一個IDependencyResolver來處理使用MVC3內置服務位置機制的依賴關係解析。如果您搜索MEF + MVC,網上有很多例子。
+0

我選擇了您建議的第一個解決方案,並在Application_Start中創建一個單一的DirectoryCatalog。它的工作速度很快。謝謝。 Ps:我已經閱讀過有關'保真設計'的文章。網絡「,但沒有理解他們如何幫助我解決這個問題。 – Martin 2012-07-25 09:54:57

+0

@Martin - 這些例子使用我在上面第2項中討論過的實現 - 這與您爲項目採用的方法不同,可能爲什麼他們沒有幫助您。 – 2012-07-25 10:10:10

+2

這就是說,你是目前爲你的構造函數設計的類沒有隱藏它的依賴關係,並且類自身構成了它自己。雖然這確實起作用,但更好的設計是將「ICustomService」作爲參數傳遞給構造函數,因爲這允許API表示其依賴性需求。這會導致你使用Item#2(上面)。 – 2012-07-25 10:12:34

1

我懷疑這是因爲每個控制器實例正在重建一個CompositionContainer,看起來好像有一些磁盤訪問。

您可以將CompositionContainer初始化移入Application_Start嗎?

+0

謝謝。我嘗試過,但並沒有讓它變得更快。正如@Matthew Abbott在他的回答中所說的那樣,創建一個CompositionContainer並不是一項緊迫的任務。 – Martin 2012-07-25 09:18:11

1

我並沒有真正使用MEF,但我認爲您的解決方案會掃描bin文件夾中的每個程序集以搜索導入/導出屬性並編寫應用程序。

我不認爲這是正確的方式來使用MEF,控制器不應該調用任何MEF相關的方法。

如果您爲每個請求配置一個DI容器,看起來類似。

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

+0

感謝您對我們文章的指針。自發布以來我們經歷了一些迭代(一個全新的合成引擎!),所以Composition Provider當前正在以演示形式分發 - http://mef.codeplex上的Microsoft.Composition.Demos.Web.Mvc。 com/SourceControl/list/changesets - 而不是通過NuGet。更多信息在這裏:http://mef.codeplex.com/discussions/361444。乾杯! – 2012-07-25 17:40:20