我正在构建一个数据库导入应用程序而不是我想要的可扩展性(可以根据需要添加自定义数据库模型)。我的基本组件具有扩展类型必须实现的方法: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也总是空的。
我设置错误了什么?如何获取扩展组件类型的列表?
答案 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 );