使用MEF导入导出的对象

时间:2010-06-10 09:48:10

标签: c# ioc-container mef

如果这个问题已被问过100次,我很抱歉,但我真的很难让它发挥作用。

说我有三个项目。

  • Core.dll
    • 有通用接口
  • Shell.exe
    • 加载程序集文件夹中的所有模块。
    • 引用Core.dll
  • ModuleA.dll
    • 导出名称,模块版本。
    • 引用Core.dll

Shell.exe有一个[导出],其中包含我需要注入所有已加载模块的第三方应用程序的单个实例。

到目前为止,我在Shell.exe中的代码是:

static void Main(string[] args)
{
        ThirdPartyApp map = new ThirdPartyApp();

        var ad = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        var dircatalog = new DirectoryCatalog(".");
        var a = new AggregateCatalog(dircatalog, ad);

        // Not to sure what to do here.
}

class Test
{
    [Export(typeof(ThirdPartyApp))]
    public ThirdPartyApp Instance { get; set; }

    [Import(typeof(IModule))]
    public IModule Module { get; set; }
}

我需要创建一个Test实例,并从Instance方法加载map Main然后从执行目录中的ModuleA.dll加载模块然后[导入] ] Instance进入加载的模块。

ModuleA我有一个这样的课程:

[Export(IModule)]
class Module : IModule
{
    [Import(ThirdPartyApp)]
    public ThirdPartyApp Instance {get;set;}
}

我知道我已经走了一半我只是不知道如何将它们放在一起,主要是使用来自map的{​​{1}}实例加载测试。

任何人都可以帮我解决这个问题。

2 个答案:

答案 0 :(得分:0)

我似乎能够以这种方式工作,在Test类的构造函数中(是的,我知道不在构造函数中工作,我会将其移出):

public Test()
    {
        ThirdPartyApp map = new ThirdPartyApp();
        this.MapInfoInstance = map;

        //What directory to look for!
        String strPath = AssemblyDirectory;
        using (var Catalog = new AggregateCatalog())
        {
            DirectoryCatalog directorywatcher = new DirectoryCatalog(strPath, "*.dll");
            Catalog.Catalogs.Add(directorywatcher);
            CompositionBatch batch = new CompositionBatch();
            batch.AddPart(this);
            CompositionContainer container = new CompositionContainer(Catalog);
            //get all the exports and load them into the appropriate list tagged with the importmany
            container.Compose(batch);

            foreach (var part in Catalog.Parts)
            {
                container.SatisfyImportsOnce(part);
            }
        }

        Module.Run();
    }

答案 1 :(得分:0)

您的主要方法应该如下所示:

static void Main(string[] args)
{   
    var exeCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    var dircatalog = new DirectoryCatalog(".");
    var aggregateCatalog = new AggregateCatalog(exeCatalog, dirCatalog);
    var container = new CompositionContainer(aggregateCatalog);
    var program = container.GetExportedValue<Program>();

    program.Run();
}

要使ThirdPartyApp类的实例可用作模块可导入的部件,您有两种选择。第一种是使用ComposeExportedValue扩展方法将此类实例显式添加到容器中,如下所示:

container.ComposeExportedValue<ThirdPartyApp>(new ThirdPartyApp());

或者,你可以通过一个像这样的类来导出它:

public class ThirdPartyAppExporter
{
    private readonly ThirdPartyApp thirdPartyApp = new ThirdPartyApp();

    [Export]
    public ThirdPartyApp ThirdPartyApp { get { return thirdPartyApp; } }
}