2013-07-26 385 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 
相关问题