2013-07-26 141 views
0

我有一個使用MEF實現插件框架的ASP.NET MVC應用程序。插件是存在於應用程序的bin目錄中的單獨的DLL。插件通常會導出一個或多個像這樣的控制器...組成由表演作品的班級未導入的部分的好方法是什麼?

<Export(GetType(IController))> 
<MYAPP_Interfaces.Attributes.MVCPluginMetadata(
    "SomePlugin", 
    "A Description for the plugin", 
    "A Readable Name", 
    {"ScriptsForThePlugin.js"}, 
    {"StylesForThePlugin.css"}, 
    Enumerations.MVCPluginType.DataView, 
    "DefaultActionName")> 
<PartCreationPolicy(CreationPolicy.NonShared)> 
Public Class MyPluginController 
    Inherits System.Web.Mvc.Controller 

    <Import()> 
    Private m_objHost As IWebHost 

...等等。

這一切工作正常,主機應用程序包括在ImportMany財產所有控制器,並且以通常的方式組成本身在創建。因此,m_objHost自動填充,控制器可以訪問主機應用程序提供的所有內容,例如日誌和有關用戶的信息以及他們當前正在處理的內容等等。

我的問題與我的模型做的,並且我有一個插件任何DAL或實用程序類。這些類通常需要來自IWebHost對象的信息。但是,主持人不需要了解這些類,所以他們不包含在作文中。因爲它們不是組成,如果他們想要一個IWebHost參考他們每個人都有撰寫自己在實例,像這樣:

Public Class MyModel 

<Import()> 
Private m_objHost As IWebHost 

<Import()> 
Private m_objLog As ILog 


Public Sub New() 
    Compose() 
End Sub 

... 

Private Sub Compose() 
    Try 
     Dim objCatalog As New AggregateCatalog 
     objCatalog.Catalogs.Add(New DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory & "bin")) 
     Dim container As New CompositionContainer(objCatalog) 
     container.ComposeParts(Me) 
    Catch ex As Exception 
     If m_objLog IsNot Nothing Then 
      m_objLog.writeError(ex) 
     End If 
    End Try 
End Sub 
End Class 

所以我的主要問題可以分爲兩個部分:

  1. 是有20個左右的類在實例化時執行組合的任何明顯的性能問題?我目前只有一些,如果有一擊就不明顯。 換句話說,我是否需要改變這一策略?它違反了DRY,因爲我在每個班級都有Compose方法,但我可以學會忍受它。

  2. 有沒有更好的辦法?如何在主應用程序中處理單個組合,負責填充插件中的所有類,包括那些未在執行主構圖的類中導入的類?

我已經考慮了以下幾點:

  • 擁有全系車型和實用工具類和實現任何一個標記接口,使用該接口作爲合同出口它們,然後在主機導入它們類,即使宿主類不需要它們。我認爲這是一種比我所擁有的更糟糕的設計,我不想這樣做。不過,我願意傾聽贊成這一觀點的論據。

  • 在需要它的每個插件中都有一個類,它實現IWebHost,它充當主應用程序導出的類的包裝。我仍然需要在每個插件中進行組合,但至少每個插件只能使用一次。這對我來說似乎沒有問題。

在此先感謝您提供的任何幫助以及閱讀本文的整篇小說。

回答

1

我結束了添加類像下面的一個需要它的插件。我有一個用於插件的項目模板,所以我可能只是將該類添加到該模板。

任何需要來自主機的類都可以通過調用PluginUtility.Host來訪問它。

Public Class PluginUtility 

    <Import()> 
    Private m_objHost As IWebHost 

    Private Shared m_objInstance As PluginUtility 

    Private Sub New() 
     Compose() 
    End Sub 

    Public Shared ReadOnly Property Host As IWebHost 
     Get 
      If m_objInstance Is Nothing Then 
       m_objInstance = New PluginUtility 
      End If 
      Return m_objInstance.m_objHost 
     End Get 
    End Property 

    Private Sub Compose() 
     Try 
      Dim objCatalog As New AggregateCatalog 
      objCatalog.Catalogs.Add(New DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory & "bin")) 
      Dim container As New CompositionContainer(objCatalog) 
     container.ComposeParts(Me) 
     Catch ex As Exception 
      Console.Write("Could not compose to get a reference to the host") 
     End Try 
    End Sub 
End Class 
相關問題