Tag: mef

如何在MEF容器中交换/替换共享(单例)对象?

这可能很简单,但由于我是MEF领域的新手,这就是为什么我难以找到问题的解决方案。 我正在使用WPF + Prism和MEF作为DI容器的应用程序。 我想将我的对象(即RuleFile )与每个应用程序实例RuleFile ,方法是将它与文件说法RuleFile1.ruleapp相关联。 因此,我使用属性[PartCreationPolicy(CreationPolicy.Shared)]进行了[PartCreationPolicy(CreationPolicy.Shared)] ,将其视为单例,以便它在整个应用程序中与每个应用程序实例保持相同。 [Serializable()] [Export] [PartCreationPolicy(CreationPolicy.Shared)] public class RuleFile : NotifyPropertyChanged, IRuleFile { } 接下来,在ViewModel [ImportingContructor] ,如下所示,该对象与所需的相同。 [ImportingConstructor] public RuleViewModel(RuleFile ruleFile) [ImportingConstructor] public SchemaViewModel(RuleFile ruleFile) 到现在为止一切顺利。 使用下面的代码,我试图得到传递给视图模型的相同导出对象,如上所述,但container.GetExportedValue()给出一个不同的新对象引用: var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); var exportObj = container.GetExportedValue(); 问题1:为什么我得到一个不同的引用虽然对象应该与CreationPolicy.Shared的单例对象相同? 问题2:最终,所有的努力都是用MEF DI容器中的反序列化对象来交换/替换RuleFile导出的对象?

根据当前进程是x32还是x64动态加载程序集

我有一些动态加载程序集的代码,具体取决于Environment.Is64BitProcess属性的结果,然后根据需要使用它。 这是MEF可以自动完成的,而不必使用环境和汇编类吗? 要么 我是否必须为MEF编写某种扩展来实现这一目标? 框架版本:.Net 4.0

使用MEF进行Winforms

我有一个使用不同选项卡的winforms应用程序。 我想使用MEF能够添加更多在启动时导入的选项卡。 我很难搞清楚如何去做这件事。 编辑:这是我做的。 我拿了主要的winforms类并将其条带化,以便只有一个TabControl,我通过一个接口向每个TabPage公开。 然后我还创建了第二个接口ITab,我与MEF一起使用以获取tabpage,然后将其添加到主tabcontrol。 要创建一个新的标签页,我只需添加一个新表单,然后向其添加一个tabcontrol并设计标签页。 我将ITab界面添加到新表单并添加以下方法将页面移动到主表单。 public void MoveTabPages(IForm fm) { while (this.tabControl1.Controls.Count > 0) { fm.tab.Controls.Add(this.tabControl1.Controls[0]); } } 事件委托和所有好东西都可以工作,只要它们只引用表单类中的内容即可。 这是完整的代码。 //Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; namespace Winforms_Mef { public interface IForm { TabControl tab { get; […]

使用MEF在运行时加载插件

我的应用程序允许用户编写可在运行时实例化的插件(实现IPlugin)。 在启动时,解析插件.dll的目录,注册所有可用的插件信息。 在运行时,提供了一个GUI,允许用户创建任何插件的实例。 这很好用。 但现在我看到了MEF,并希望我能做同样的事情,但是以更优雅的方式代码化。 我到目前为止用MEF工作的东西 :在启动时我正在导入目录中的所有插件(导出IPlugin)并读出名称,类别,作者等信息……这些信息被编码为导出的元数据属性到插件类。 导入是懒惰的,因此所有插件都不会在启动时实例化,这很重要。 问题是,现在我没有看到在运行时优雅地实例化所选插件的方法,因为插件构造函数是一个导入构造函数,它正在导入对IPluginHost的引用(它需要立即进行一些初始化)的额外复杂性。 与plugininfo一起,我在启动期间将相应的Export保存在字典中,因此当GUI要求实例化给定特定plugininfo的插件时,我可以访问Export(其中Export.Value是我的实际IPlugin)。 但是从那里我如何创建插件的实例并将其与IPluginHost组合? 我收集我应该编写自己的ExportProvider,只要有人要求它就能为IPluginHost提供服务,但我无法访问程序集或特定插件的类型,这些插件可以让我将它添加到目录中,添加目录和ExportProvider到容器并在该容器上调用.ComposeParts。 我希望我能清楚地解决问题,如果没有,让我尝试一下这个问题的简短版本 :MEF的标准用例是不是一个程序,它在启动时延迟加载插件来解析可用的插件信息然后在运行时创建给定特定plugininfos的特定实例? 获得所涉及步骤的代码行是很好的。

如何在WPF中重新编译空的DirectoryCatalog for MEF

我有这个步骤的应用程序: 启动应用程序和ConfigureAggregateCatalog 登录用户到应用程序 将DLL MEF模块下载到名为“Modules”的目录 刷新目录目录 – 有一个问题 我有空目录’模块’后下载DLL我试图加载模块但没有成功。 我在线上有一个错误,我称之为DirectoryCatalog.Refresh() 用户代码未处理System.ComponentModel.Composition.ChangeRejectedException消息=组合保持不变。 由于以下错误,更改被拒绝:组合产生多个组合错误,有14个根本原因。 根本原因如下。 查看CompositionException.Errors属性以获取更多详细信息。 1)由不可重组的导入阻止的导出变化’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleInitializer..ctor(Parameter =“downloadedPartCatalogs”,ContractName =“Microsoft.Practices.Prism.MefExtensions.Modularity.DownloadedPartCatalogCollection”)’部分’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleInitializer’。 2)部分’Microsoft.Practices上的非重组导入’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager.mefFileModuleTypeLoader(ContractName =“Microsoft.Practices.Prism.MefExtensions.Modularity.MefFileModuleTypeLoader”)’阻止了导出的变化。 Prism.MefExtensions.Modularity.MefModuleManager”。 3)由不可重组的导入’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager..ctor(Parameter =“moduleInitializer”,ContractName =“Microsoft.Practices.Prism.Modularity.IModuleInitializer”)’阻止出口的变化’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager’。 4)部分’Microsoft.Practices’中不可重组的导入’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager.mefFileModuleTypeLoader(ContractName =“Microsoft.Practices.Prism.MefExtensions.Modularity.MefFileModuleTypeLoader”)’阻止了导出的变化。 Prism.MefExtensions.Modularity.MefModuleManager”。 5)由不可重组的导入’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager..ctor(Parameter =“moduleInitializer”,ContractName =“Microsoft.Practices.Prism.Modularity.IModuleInitializer”)’阻止出口的变化’Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager’。 6)部分’GXBilling.ViewsModels.ShellViewModel’上的不可重组导入’GXBilling.ViewsModels.ShellViewModel.ModuleManager(ContractName =“Microsoft.Practices.Prism.Modularity.IModuleManager”)’阻止了导出的变化。 7)发现多个导出匹配约束’((exportDefinition.ContractName ==“Microsoft.Practices.Prism.Regions.RegionAdapterMappings”)AndAlso(exportDefinition.Metadata.ContainsKey(“ExportTypeIdentity”)AndAlso“Microsoft.Practices。 Prism.Regions.RegionAdapterMappings” .Equals(exportDefinition.Metadata.get_Item( “ExportTypeIdentity”))))”。 导致:无法设置导入’Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefDelayedRegionCreationBehavior..ctor(Parameter =“regionAdapterMappings”,ContractName =“Microsoft.Practices.Prism.Regions.RegionAdapterMappings”)”’部分’微软。 Practices.Prism.MefExtensions.Regions.Behaviors.MefDelayedRegionCreationBehavior”。 元素:Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefDelayedRegionCreationBehavior..ctor(Parameter =“regionAdapterMappings”,ContractName =“Microsoft.Practices.Prism.Regions.RegionAdapterMappings”) – > Microsoft.Practices.Prism.MefExtensions。 Regions.Behaviors.MefDelayedRegionCreationBehavior – > AssemblyCatalog(Assembly =“Microsoft.Practices.Prism.MefExtensions,Version = 4.0.0.0,Culture = neutral,PublicKeyToken […]

MEF:来自Type的GetExportedValue?

使用MEF我可以创建并加载这样的类型: var view = Container.GetExportedValue(); 现在我想要做的是: Type t = typeof(MyView); var view = Container.GetExportedValue(); (当然,类型可能包含与MyView不同的内容)。 使用genericsGetExportedValue 是不可能的 – 有没有其他方法来实现这一点?

使用来自另一个MEF程序集的类而不引用它

我有2个MEF组件。 让它成为组件A和组件B. 我需要的是能够从组件A中的组件B访问类而不参考它。 然后我想手动实例化该类的对象。 目前我看到MEF允许使用[Import]自动实例化对象。 它使用需要引用的接口。 我可以使用其他程序集中的数据类型而不引用它吗? MEF是否支持这种机制?

MEF,为什么创建同一个导出插件的相同副本?

(1)使用下面的代码我在我的容器中得到了两个相同的导出插件,我想知道为什么: (2)我真正无法实现的其他问题:如何扩展框架以处理不同的插件类型(例如,有多个不同类型的导入,或者一个导入将所有插件存储在动态IEnumerable中)。 我想在我的静态包装类中提供一个generics方法,该方法将发现的插件作为类型和匹配元数据的函数返回。 导出的插件(位于单独的dll中,其位置在构建DirectoryCatalog时指向。 [Export(typeof(IPlugin))] //<—- If this line is commented out then only one item is imported (why?) [PluginAttribute(typeof(StrategyPlugin_Test1), "StrategyPlugin", "Plugin1")] public class StrategyPlugin_Test1 : IPlugin { public void DoSomething() { Console.WriteLine("I do something"); } } 以下代码定义了强类型元数据和导入,以及执行MEF函数并应该保存已发现插件的静态类: [MetadataAttribute] [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class PluginAttribute : ExportAttribute { public Type PluginType { get; set; […]

MEF通用import

我有以下使用MEF的示例代码: public interface IFoo {} public class Foo : IFoo {} [Export(typeof(IFoo))] public class Foo : Foo {} public class Bar { [Import] private readonly IFoo foo; } static void Main() { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); var container = new CompositionContainer(catalog); container.ComposeParts(); var bar = new Bar(); //bar.foo would be null } […]

运行具有不同版本的依赖关系dll的插件的推荐方法是什么?

我有一个WCF插件服务,通过MEF加载插件并运行它们。 每个插件都是一个具有多个dll的目录,它实现了特定的接口。 我使用MEF( DirectoryCatalog )在同一个AppDomain中加载所有插件,并以通用方式运行它们(使用reflection)。 现在假设我有两个带有dll依赖项的插件: Plugin1 —-> Entities 1.0.0.1 Plugin2 —-> Entities 1.0.0.2 我在1.0.0.2中添加了一些新实体。 当我运行插件时,我得到一个偶然的错误,即新的实体在dll中不存在。 我猜错误发生,因为我在相同的AppDomain中运行代码,加载的第一个Entities.dll是将为我的所有插件提供服务的那个。 那么,如何在不创建新的appdomain的情况下运行隔离的每个插件? 有什么方法可以告诉MEF以某种方式加载所有插件依赖项? 我在网上看到了几个解决方案: 为每个插件创建一个新的appdomain – 我不想去那里 。 使用 – 当我第一次尝试它时,这不起作用,我不希望我的插件服务器更新每个程序集依赖项版本更改。 另外,我希望能够运行具有不同组件版本的插件。 用snk签署程序集 – 我还没有尝试这个,我不确定这个解决方案是否有效。 框架将如何知道他需要加载不同的程序集? 这与具有不同版本的程序集有何不同? 我是否需要以某种方式配置我的服务才能使其工作? 有没有人对我有更好的想法? 什么是运行隔离插件的推荐方法?