代码之家  ›  专栏  ›  技术社区  ›  JCCyC

如果在目录中发现新的DLL,则对DirectoryCatalog调用Refresh()会抛出ChangeRejectedException

  •  8
  • JCCyC  · 技术社区  · 17 年前

    我在做实验 MEF

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ProbeContract
    {
        public interface IProbe
        {
            int DoProbe(string what);
            List<string> GetCapabilities();
        }
    }
    

    我创建了一个示例控制台程序,该程序从其自己的程序集中加载“插件”,如果找到任何插件,则从其中放置其他DLL的目录中加载。无论插件目录为空(仅调用“本机”插件)还是具有兼容的DLL,程序都能正常工作。但是。..如果在循环迭代之间添加了一个新的DLL,DirectoryCatalog的Refresh()方法会抛出一个ChangeRejectedException,解释如下:

    组成保持不变。这 由于以下原因,更改被拒绝 产生了一个单一的构图错误。 根本原因如下。

    (合同名称=“ProbeConstructor.IProbe”)'

    程序如下,后面是我尝试添加的DLL的代码。我做错了什么?

    using System;
    using System.IO;
    using System.Reflection;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using ProbeContract;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    
    namespace MEFTest
    {
        class Program
        {
            [ImportMany]
            IEnumerable<IProbe> ProberSet { get; set; }
    
            CompositionContainer exportContainer;
            DirectoryCatalog pluginCatalog;
            AggregateCatalog catalog;
    
            private void Run()
            {
                catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
                string myExecName = Assembly.GetExecutingAssembly().Location;
                string myPath = Path.GetDirectoryName(myExecName);
                pluginCatalog = new DirectoryCatalog(myPath + "/Plugins");
                catalog.Catalogs.Add(pluginCatalog);
                exportContainer = new CompositionContainer(catalog);
    
                CompositionBatch compBatch = new CompositionBatch();
                compBatch.AddPart(this);
                compBatch.AddPart(catalog);
                exportContainer.Compose(compBatch);
    
                for (; ; )
                {
                    Console.Write("Press any key to run all probes: ");
                    Console.ReadKey(true);
                    Console.WriteLine();
                    pluginCatalog.Refresh();
                    foreach (var Prober in ProberSet)
                    {
                        Prober.DoProbe("gizmo");
                    }
                }
            }
    
            static void Main(string[] args)
            {
                Program p = new Program();
                p.Run();
            }
        }
    }
    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.Composition;
    using ProbeContract;
    
    namespace OtherProbes
    {
        [Export(typeof(IProbe))]
        public class SpankyNewProber : IProbe
        {
            public int DoProbe(string what)
            {
                Console.WriteLine("I'm Spanky and New and I'm probing [{0}]", what);
                return 0;
            }
    
            public List<string> GetCapabilities()
            {
                List<string> retVal = new List<string>();
                retVal.Add("spanky");
                retVal.Add("new");
                return retVal;
            }
        }
    }
    
    1 回复  |  直到 12 年前
        1
  •  13
  •   Wes Haggard    17 年前

    我假设你正在使用MEF预览版6,因为你看到了拒绝异常。您看到更改被拒绝的原因是您的ProberSet不能重新组合。尝试将ProberSet导入更改为:

    [ImportMany(AllowRecomposition=true)]        
    IEnumerable<IProbe> ProberSet { get; set; }
    

    这样做将允许在组合此导入后将新的IProbe导出引入目录/容器。

    这里的想法是,一旦你得到一个稳定的组合,我们就会拒绝任何可能破坏该组合的更改,在你的情况下,你说你想要一组不可重新组合的IProbe对象,所以在初始设置后添加新的IProbes会违反这一要求。