Tag: prism 5

如何在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导出的对象?

Prism 5 DelegateCommandBase.RaiseCanExecuteChanged抛出InvalidOperationException

我刚刚从Prism 4.1到5进行了更新,过去工作正常的代码现在会抛出InvalidOperationExceptions。 我怀疑根本原因是更新的异步DelegateCommands没有正确地编组到UI线程。 我需要能够从任何线程调用command.RaiseCanExecuteChanged()并为此在UI线程上引发CanExecuteChanged事件。 Prism文档说这就是RaiseCanExecuteChanged()方法应该做的事情。 然而,随着Prism 5的更新,它不再有效。 CanExecuteChanged事件在非UI线程上调用,我获得下游InvalidOperationExceptions,因为在这个非UI线程上访问UI元素。 这是提供解决方案提示的Prism文档: DelegateCommand包括对异步处理程序的支持,并已移至Prism.Mvvm可移植类库。 DelegateCommand和CompositeCommand都使用WeakEventHandlerManager来引发CanExecuteChanged事件。 必须首先在UI线程上构造WeakEventHandlerManager,以正确获取对UI线程的SynchronizationContext的引用。 但是,WeakEventHandlerManager是静态的,所以我无法构造它… 根据Prism文档,有谁知道如何在UI线程上构建WeakEventHandlerManager? 这是一个失败的unit testing,可以重现问题: [TestMethod] public async Task Fails() { bool canExecute = false; var command = new DelegateCommand(() => Console.WriteLine(@”Execute”), () => { Console.WriteLine(@”CanExecute”); return canExecute; }); var button = new Button(); button.Command = command; Assert.IsFalse(button.IsEnabled); canExecute = true; // Calling RaiseCanExecuteChanged […]