MEF从目录加载插件

时间:2012-06-11 20:18:05

标签: c# location mef .net-assembly

我与MEF合作,我正在寻找如何通过MEF找到插件的其他方式更改插件位置的URL,我想更改此行

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

我想删除此网址,因为我需要在另一台计算机上部署我的应用程序

这是我的功能:

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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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);

这是我的解决方案,为所有人着想

答案 2 :(得分:2)

两个选项。

  1. 使用当前目录作为插件的根目录。 Environment.CurrentDirectory应该指向正确的方向。
  2. 使用app.config指定要存储的插件的目录。

答案 3 :(得分:1)

如果您的方法知道要实例化的类型,您可以使用Assembly的{​​{1}}属性,这是 my 的典型属性*域*库;否则,您可以使用Type。我并不特别喜欢Assembly.GetExecutingAssembly()GetExecutingAssembly() ......:

GetCallingAssembly()

除此之外,您可以添加DirectoryCatalogs - 通过 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; } } 文件,序列化目录列表等。但是,您可以在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 } 作为搜索路径是执行程序集目录的合法快捷方式,但请记住,将搜索所有程序集以查找已完成的部分 - 即匹配"." / {{1}对象。我建议使用特定模式。微软的例子不是最佳做法。如果您希望任何插件后缀为Import,请将其作为搜索模式的一部分。