简体   繁体   English

Caliburn.micro如何使用MEF导入自定义插件

[英]How Caliburn.micro uses MEF to import custom plugins

I have some extension plugins in the plugins directory. 我在plugins目录中有一些扩展插件。 I am going to import plugins in ViewModel and use it, but I can not import it successfully. 我将在ViewModel中导入插件并使用它,但无法成功导入。 I think I have no way to successfully configure the Configure, seek advice。 我想我无法成功配置Configure,请教。

BootStrapper: 引导程序:

public class AppBootstrapper : BootstrapperBase
{
    private CompositionContainer container;

    public AppBootstrapper()
    {
        Initialize();
    }

    protected override void Configure()
    {
        string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
        if (!Directory.Exists(pluginPath))
            Directory.CreateDirectory(pluginPath);

        var fi            = new DirectoryInfo(pluginPath).GetFiles("*.dll");
        AssemblySource.Instance.AddRange(fi.Select(fileInfo => Assembly.LoadFrom(fileInfo.FullName)));

        var catalog       = new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
        var batch         = new CompositionBatch();
        container         = new CompositionContainer(catalog);

        batch.AddExportedValue(container);
        batch.AddExportedValue<IWindowManager>(new WindowManager());

        batch.AddExportedValue<IEventAggregator>(new EventAggregator());
        batch.AddExportedValue(catalog);

        container.Compose(batch);
    }

    protected override void BuildUp(object instance)
    {
        base.BuildUp(instance);
    }

    protected override object GetInstance(Type service, string key)
    {
        var contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;
        var exports = this.container.GetExportedValues<object>(contract);

        if (exports.Any())
        {
            return exports.First();
        }

        throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return this.container.GetExportedValues<object>(AttributedModelServices.GetContractName(service));
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        DisplayRootViewFor<IShell>();
    }
}

ViewModel 视图模型

 [ImportMany]
 IEnumerable<Lazy<IPlugin, IPluginsMetaData>> plugins;

In fact, my Bootstrapper and no problem, the problem appears in my IPlugin class. 实际上,我的Bootstrapper并没有问题,该问题出现在我的IPlugin类中。 In the process of finding the problem, I also found Bootstrapper Configure method in another way to write. 在查找问题的过程中,我还找到了Bootstrapper Configure方法的另一种编写方式。 I will put the entire plug-in code are posted for everyone to refer to the next ~ 我将把整个插件代码都贴出来给大家参考下〜

BootStrapper Configure BootStrapper配置

protected override void Configure()
{
    var catalog = new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
    var batch   = new CompositionBatch();
    var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");

    if (!Directory.Exists(path))
        Directory.CreateDirectory(path);

    catalog.Catalogs.Add(new DirectoryCatalog(path));
    container = new CompositionContainer(catalog);

    batch.AddExportedValue(container);
    batch.AddExportedValue<IWindowManager>(new WindowManager());

    batch.AddExportedValue<IEventAggregator>(new EventAggregator());
    batch.AddExportedValue(catalog);

    container.Compose(batch);
}

ShellViewModel ShellViewModel

[Export(typeof(IShell))] 
public class ShellViewModel : Conductor<object>, IShell
{
    [ImportMany]
    IEnumerable<Lazy<IPlugin, IPluginMetaData>> plugins;
}

IPlugin IPlugin

public interface IPlugin
{
     void Do();
}

public interface IPluginMetaData 
{
     string Name { get; }

     string Code { get; }

     //[... more attribute ...]
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginExportAttribute : ExportAttribute, IPluginMetaData
{
    public string Name { get; set; }

    public string Code { get; set; }   

    //[... more attribute ...]

    public PluginExportAttribute() : base(typeof(IPlugin)) { }
}

PluginOne PluginOne

[PluginExport(Name = "PluginOne", Code = "Key")]
public class PluginOne : IPlugin
{
     public void Do()
     {
       Console.WriteLine("I'm PluginOne");
     } 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM