10

我与 MEF 合作,我正在寻找如何通过 MEF 找到插件的另一种方式更改插件位置的 url,我想更改这一行

Assembly.LoadFrom(@"C:\julia\project\project.Plugin.Nav\bin\Debug\NavPlugin.dll")));

我想删除这个 url,因为我需要在另一台机器上部署我的应用程序

这是我的功能:

public void AssembleCalculatorComponents()
{
   try
   {
       //var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
       //var container = new CompositionContainer(catalog);
       //container.ComposeParts(this);
       var catalog = new AggregateCatalog();

       catalog.Catalogs.Add(new AssemblyCatalog(Assembly.LoadFrom(@"C:\yosra\project\project.Plugin.Nav\bin\Debug\NavPlugin.dll")));
       var container = new CompositionContainer(catalog);

       container.ComposeParts(this);
    }
    catch (Exception ex)
    {
       throw ex;
    }
 }

你能帮我么?

谢谢

4

4 回答 4

16

您可以使用DirectoryCatalog类让 MEF 扫描特定目录以查找满足您的导入的程序集。

var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog("."));
var container = new CompositionContainer(catalog);

以上将添加 AppDomain 用于定位程序集的基本目录(通常是包含可执行文件的目录,除非配置更改)到聚合目录。您可能还想添加当前正在执行的程序集,尽管这不是必需的。

var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
catalog.Catalogs.Add(new DirectoryCatalog("."));
var container = new CompositionContainer(catalog);

有关 DirectoryCatalog 的 MSDN 的更多信息:http: //msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.aspx

于 2012-06-11T20:28:22.670 回答
5

再次您好,感谢您的回复,所以我的问题是直接加载插件,所以我创建一个目录并将我的插件放在这个文件夹中,所以我找到了这个解决方案

public void AssembleCalculatorComponents()
        {


            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            Console.WriteLine(path);
            //Check the directory exists
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            Console.WriteLine(path);
            string assemblyName = Assembly.GetEntryAssembly().FullName;
            Console.WriteLine(assemblyName);
            //Create an assembly catalog of the assemblies with exports
            var catalog = new AggregateCatalog(
                new AssemblyCatalog(Assembly.GetExecutingAssembly().Location),
                new AssemblyCatalog(Assembly.Load(assemblyName)),
                new DirectoryCatalog(path, "*.dll"));

            //Create a composition container
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);

这是我的解决方案,为所有人考虑

于 2012-06-13T13:08:59.887 回答
2

两种选择。

  1. 使用当前目录作为插件的根目录。Environment.CurrentDirectory 应该为您指明正确的方向。
  2. 使用 app.config 指定要存储插件的目录。
于 2012-06-11T20:25:59.700 回答
1

如果您的方法知道要实例化的类型,则可以使用我的*Domain* 库的典型Assembly属性;否则,您可以使用. 我不是特别喜欢或...: TypeAssembly.GetExecutingAssembly()GetExecutingAssembly()GetCallingAssembly()

  public void AssembleCalculatorComponents() {
     try {
        var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
     // OR
        asmCatalog = new AssemblyCatalog(typeof(TObject).Assembly); // replace TObject with object's actual type
        var aggregateCatalog = new AggregateCatalog(asmCatalog);
        // 
        AddDirectoryCatalogs(aggregateCatalog.Catalogs));
        var container = new CompositionContainer(catalog);

        // assuming this class has the member(s) to be composed.
        container.ComposeParts(this);
     } catch (Exception ex) {
        throw ex;
     }
  } 

除此之外,您可以添加 DirectoryCatalogs - 通过app.config文件、序列化的目录列表等。不过,您可以在您的目录中指定一个默认目录app.config- 这是我推荐的。然后,假设您正在使用Settings

private readonly Settings settings = Settings.Default;

void AddDirectoryCatalogs(ICollection<ComposablePartCatalog> Catalogs agrCatalogs ) {
    agrCatalogs.Add(new DirectoryCatalog(settings.DefaultPath, settings.DefaultPattern));
    // add more directory catalogs
}

虽然"."用作搜索路径是执行程序集目录的合法快捷方式,但请记住,将搜索所有程序集以查找满足部分 - 即匹配Import/Export对象。我建议使用特定模式。Microsoft 的示例并不以最佳实践而闻名。如果您希望任何插件以 . 为后缀Plugin.dll,请将其作为搜索模式的一部分。

于 2012-06-11T20:33:40.250 回答