将MEF与抽象基类一起使用

时间:2014-01-23 15:49:21

标签: c# mef composition

我正在构建一个数据库导入应用程序而不是我想要的可扩展性(可以根据需要添加自定义数据库模型)。我的基本组件具有扩展类型必须实现的方法:MapData&保存数据。

我将base定义为抽象类,当扩展类型在同一名称空间中时,一切都有效。但是,我想在运行时使用MEF在不同的命名空间中导入扩展类型,但我无法弄清楚如何做到这一点。

基类:

namespace Program
{
   public abstract class Component
   {
      public abstract string TypeName { get; }
      public abstract DataSet MapData( DataSet db );
      public abstract bool SaveData();
   }
}

扩展类(在一个单独的项目中):

using Program.Component;
namespace ExtendedType
{
   [Export( typeof( Component )]
   class Type1 : Component
   {
       public override string TypeName { get { return "Type1" } }
       public override DataSet MapData( DataSet db )
       {
          // create various object models from db here 
          return db;
       }
       public override bool SaveData()
       {
          // save object models 
          return true;
       }
   }
}

导入所有扩展类型的程序:

namespace Program
{
   [ImportMany( typeof( Component ) )]
   public IEnumerable<Component> componentTypes;

   public Program()
   {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add( new AssemblyCatalog( typeof( Component ).Assembly ) );
        container = new CompositionContainer( catalog );
        this.container.ComposeParts( this );
   }
}

根据我所读到的,IEnumerable上的[ImportMany]属性应该在运行时填充,但它总是为空。 CompositionContainer也总是空的。

我设置错误了什么?如何获取扩展组件类型的列表?

2 个答案:

答案 0 :(得分:2)

MEF将仅搜索CompositionContainer定义的类型/程序集集。在这种情况下,Type1的程序集不在那里,因此从未找到它。为了使这项工作正常,您还需要在Type1中包含CompositionContainer的程序集。

 catalog.Catalogs.Add( new AssemblyCatalog( typeof( Type1 ).Assembly )

答案 1 :(得分:0)

我最终为MEF组件创建了一个Extensions目录,以便在App.Config中设置变量,并在其他项目的Build目录中指向该目录。感谢@JaredPar的帮助。

 var extensionFolder = ConfigurationManager.AppSettings["ExtensionPath"];
 var solutionPath = Directory.GetParent( System.IO.Directory.GetCurrentDirectory() ).Parent.FullName;
 var catalog = new AggregateCatalog();
 catalog.Catalogs.Add( new DirectoryCatalog( solutionPath + extensionFolder ) );
 var container = new CompositionContainer( catalog );
 container.ComposeParts( this );