Using MEF with abstract base class

喜你入骨 提交于 2019-12-12 02:26:06

问题


I'm building a database import app than I want to be extensible (custom db models can be added as needed). My base component has methods that extended types have to implement: MapData & SaveData.

I defined the base as an abstract class, and everything works when the extended types are in the same namespace. However, I want to use MEF to import extended types in a different namespace at runtime, but I can't figure out how to do that.

Base class:

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

Extended class (in a separate project):

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

Program to import all extended types:

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

According to what I've read, the [ImportMany] attribute on IEnumerable should fill that at runtime but it's always empty. The CompositionContainer is always empty as well.

What did I set up incorrectly? How can I get a list of the extended Component types?


回答1:


MEF will only search the set of types / assemblies that is defined by the CompositionContainer. In this case the assembly for Type1 isn't in there hence it's never found. In order or this to work you need to include the assembly for Type1 in the CompositionContainer as well.

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



回答2:


I ended up creating an Extensions directory for the MEF components to live in and setting a variable in App.Config as well as the Build directory of the other projects to point there. Thanks to @JaredPar for the help.

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


来源:https://stackoverflow.com/questions/21313016/using-mef-with-abstract-base-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!