C# 如何在MEF中使用事件聚合器?

C# 如何在MEF中使用事件聚合器?,c#,.net,prism,mef,prism-4,C#,.net,Prism,Mef,Prism 4,我正在运行最新的PRISM 4.2。不幸的是,文档中的事件聚合器教程是通过Unity而不是MEF驱动的。我不能让它在MEF下运行 App.xaml.cs public partial class App : Application { [Import] public IEventAggregator eventAggregator; protected override void OnStartup(StartupEventArgs e

我正在运行最新的PRISM 4.2。不幸的是,文档中的事件聚合器教程是通过Unity而不是MEF驱动的。我不能让它在MEF下运行

App.xaml.cs

 public partial class App : Application
    {
        [Import]
        public IEventAggregator eventAggregator;

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Bootstrapper bootstrapper = new Bootstrapper();
            bootstrapper.Run();
        }
    }
public class Bootstrapper : MefBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            return new MainWindow();
        }

        protected override void InitializeShell()
        {
            base.InitializeShell();
            App.Current.MainWindow = (Window)Shell;
            App.Current.MainWindow.Show();
        }

        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();

            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            ModuleCatalog moduleCatalog = new ModuleCatalog();

            return moduleCatalog;
        }

    }
public partial class MainWindow : Window, IView
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();  
 //In this case the HandleAppExitEvent and the subscriber that deals with this event.                   
 EventAggregatorHelper.Current.GetEvent<AppExitEvent>().   Subscribe(HandleAppExitEvent);  

            }
      //note that this method should be public 

 public void HandleAppExitEvent(string mess)
    {
       if (!String.IsNullOrEmpty(mess))
       {
          //Do whatever you need to do here.
       }
    }

    }
Bootstrapper.cs

 public partial class App : Application
    {
        [Import]
        public IEventAggregator eventAggregator;

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Bootstrapper bootstrapper = new Bootstrapper();
            bootstrapper.Run();
        }
    }
public class Bootstrapper : MefBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            return new MainWindow();
        }

        protected override void InitializeShell()
        {
            base.InitializeShell();
            App.Current.MainWindow = (Window)Shell;
            App.Current.MainWindow.Show();
        }

        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();

            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            ModuleCatalog moduleCatalog = new ModuleCatalog();

            return moduleCatalog;
        }

    }
public partial class MainWindow : Window, IView
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();  
 //In this case the HandleAppExitEvent and the subscriber that deals with this event.                   
 EventAggregatorHelper.Current.GetEvent<AppExitEvent>().   Subscribe(HandleAppExitEvent);  

            }
      //note that this method should be public 

 public void HandleAppExitEvent(string mess)
    {
       if (!String.IsNullOrEmpty(mess))
       {
          //Do whatever you need to do here.
       }
    }

    }
MainWindow.xaml.cs

 public partial class App : Application
    {
        [Import]
        public IEventAggregator eventAggregator;

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Bootstrapper bootstrapper = new Bootstrapper();
            bootstrapper.Run();
        }
    }
public class Bootstrapper : MefBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            return new MainWindow();
        }

        protected override void InitializeShell()
        {
            base.InitializeShell();
            App.Current.MainWindow = (Window)Shell;
            App.Current.MainWindow.Show();
        }

        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();

            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            ModuleCatalog moduleCatalog = new ModuleCatalog();

            return moduleCatalog;
        }

    }
public partial class MainWindow : Window, IView
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();  
 //In this case the HandleAppExitEvent and the subscriber that deals with this event.                   
 EventAggregatorHelper.Current.GetEvent<AppExitEvent>().   Subscribe(HandleAppExitEvent);  

            }
      //note that this method should be public 

 public void HandleAppExitEvent(string mess)
    {
       if (!String.IsNullOrEmpty(mess))
       {
          //Do whatever you need to do here.
       }
    }

    }
MainViewModel.cs:

[ModuleExport(typeof(MainViewModel))]
    public class MainViewModel : BindableBase, IServiceCallback
    {
        [Import]
        public IEventAggregator eventAggregator;

        [ImportingConstructor]
        public MainViewModel()
        {            
            eventAggregator.GetEvent<AppExitEvent>().Publish("");

        }
     }
[ModuleExport(typeof(MainViewModel))]
公共类MainViewModel:BindableBase,IServiceCallback
{
[进口]
公共事件聚合器;
[导入构造函数]
公共主视图模型()
{            
eventAggregator.GetEvent不再支持
ComposeExportedValue

“System.ComponentModel.Composition.Hosting.CompositionContainer”没有 不包含“ComposeExportedValue”的定义且没有扩展 方法


在引导程序类中,请使用以下方法:

protected override void ConfigureContainer()
{
     base.ConfigureContainer();
     Container.ComposeExportedValue(new EventAggregator());
}
你应该看看这篇文章,因为它更详细地回答了你的第一个和第二个问题。

更新:

如果您按照下面的方式创建一个类,它将使您的导出与导入相匹配

public class EventAggProvider
   {
     [Export(typeof(IEventAggregator))]
     public IEventAggregator eventAggregator { get { return new EventAggregator(); } }
   }

EventAggregator
不依赖于
MEF或Unity
它是由Martin Fowler创造的设计模式,它基于发布者-订阅者场景

尝试按照以下步骤操作

//这应该在您的基础结构层中

public  static class EventAggregatorHelper
{
  private static IEventAggregator _Current = new EventAggregator();
  public static IEventAggregator Current
  {
    get
    {
      return _Current;
    }
  }
}



The HandleAppExitEvent is a class declared as shown below:

public class AppExitEvent : CompositePresentationEvent<String>
{
} 

and the subscriber would be something like this:
公共静态类EventAggregatorHelper
{
私有静态IEventAggregator_Current=新事件聚合器();
公共静态励磁电流
{
得到
{
返回电流;
}
}
}
HandleAppExitEvent是一个声明如下所示的类:
公共类AppExitEvent:CompositePresentationEvent
{
} 
用户应该是这样的:
在您的main窗口中.xaml.cs

 public partial class App : Application
    {
        [Import]
        public IEventAggregator eventAggregator;

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Bootstrapper bootstrapper = new Bootstrapper();
            bootstrapper.Run();
        }
    }
public class Bootstrapper : MefBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            return new MainWindow();
        }

        protected override void InitializeShell()
        {
            base.InitializeShell();
            App.Current.MainWindow = (Window)Shell;
            App.Current.MainWindow.Show();
        }

        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();

            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            ModuleCatalog moduleCatalog = new ModuleCatalog();

            return moduleCatalog;
        }

    }
public partial class MainWindow : Window, IView
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();  
 //In this case the HandleAppExitEvent and the subscriber that deals with this event.                   
 EventAggregatorHelper.Current.GetEvent<AppExitEvent>().   Subscribe(HandleAppExitEvent);  

            }
      //note that this method should be public 

 public void HandleAppExitEvent(string mess)
    {
       if (!String.IsNullOrEmpty(mess))
       {
          //Do whatever you need to do here.
       }
    }

    }
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
DataContext=新的MainViewModel();
//在本例中,HandleAppExitEvent和处理此事件的订阅服务器。
EventAggregatorHelper.Current.GetEvent().Subscribe(HandleAppExitEvent);
}
//请注意,此方法应该是公共的
公共无效HandleAppExitEvent(字符串混乱)
{
如果(!String.IsNullOrEmpty(mess))
{
//在这里你需要做什么就做什么。
}
}
}

解决方法是舒伯特在CodePlex上回答您的问题:

作为更深入的分析,在构造函数完成之前,属性上的导入属性不会被解析。这就是为什么如果此依赖项将用于构造函数实现,则需要通过构造函数将事件聚合器依赖项作为参数注入的原因

因此,如果要使用ViewModel构造函数上的EventAggregator依赖项,则应改为使用[ImportConstructor]属性,并通过将其作为参数检索,请求容器提供EventAggregator实例:

public class MainViewModel
{
    private readonly IEventAggregator eventAggregator;

    [ImportingConstructor]
    public MainViewModel(IEventAggregator eventAggregator)
    {
       this.eventAggregator = eventAggregator;

       this.eventAggregator.GetEvent<MyEvent>().Publish("");
    }
}
public类主视图模型
{
私有只读IEventagor事件聚合器;
[导入构造函数]
公共主视图模型(IEventAggregator事件聚合器)
{
this.eventAggregator=eventAggregator;
此.eventAggregator.GetEvent().Publish(“”);
}
}
您可以在以下帖子中找到有关这两种导入替代方案的更多相关信息:


我希望这对您有所帮助,尊敬的。

现在有点晚了,但是对于您希望在属性中注入EventAggregator的情况,还有一个解决方案。实现“iPartimportSSatifiedNotification”并在“OnImportSSatified”方法中使用EventAggregator

public class MainViewModel : BindableBase,  IPartImportsSatisfiedNotification
{
    [Import]
    public IEventAggregator eventAggregator;

    public void OnImportsSatisfied()
    {
        eventAggregator.GetEvent<AppExitEvent>().Publish("");
    }
 }
public类主视图模型:BindableBase、iPartimportsAssetFiedNotification
{
[进口]
公共事件聚合器;
公共无效OnImportsAssetized()
{
eventAggregator.GetEvent().Publish(“”);
}
}

你的文章在哪里?你确定你不是指
配置聚合目录
而不是
配置容器
?我以为前者处理应用程序中的MEF易耗件。你的文章与MEF和eventagregator@K.B阅读这篇文章,作者正在使用MEF,以及他使用它的方式这里回答了这两个问题。@TYY,我刚刚尝试了你的建议,它说
ComposeExportedValue
找不到。在最新版本中,这些东西似乎已经改变了。我在3小时前写了那篇文章。我也无法让它工作。在StackOverflow中,答案应该有一个代码建议,而不是更多的文章。;)谢谢听我说。不过,你对我的答案有什么建议没有让你投赞成票吗?重点,也许是糟糕的问题解释?谢谢。完成。也接受了答案。;)