MEF导入和导出无法正常工作

时间:2017-02-13 18:47:55

标签: c# wpf xaml mvvm mef

我试图在不使用prism的情况下进行WPF应用程序。当我试图通过使用构造函数使得我的viewmodel在视图中得到它不起作用。我在我的代码中也有一个属性注入,它也给出了一个空引用。 这是因为没有覆盖复合容器,如果是这样,在没有棱镜的应用程序中如何/在何处提供复合容器。 我的代码是这样的 在xaml文件中,设计实例设置为viewmodel,cs文件设置为

MainWindow.xaml.cs

public MainWindow()
    {
        InitializeComponent();            
    }

    [ImportingConstructor]
    public MainWindow(MainWindowViewModel viewModel) :this()
    {
        this.DataContext = viewModel;
        this.ViewModel = viewModel;
    }
    public MainWindowViewModel ViewModel { get; set; }

[Export] 
public class MainWindowViewModel 
{    
}

MainWindow.xaml.cs的构造函数中的断点根本没有命中。在视图模型中,属性注入也没有命中。 我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

以下是使用PRISM 5的示例,但它在PRISM 6.2.0中的工作方式相同。

您需要从app.xaml中删除启动uri。 然后确保安装了PRISM.MEF NuGet包。 写一个像下面那样的引导程序。 (请注意,引导程序基类有一系列方法可以覆盖所有这些设置的适当位置。为简单起见,我将它全部放在一个方法中。)

public class MyBootstrapper : MefBootstrapper
{
    protected override DependencyObject CreateShell()
    {            
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(MyBootstrapper).Assembly));
        var container = new CompositionContainer(catalog);
        var shell = container.GetExport<MainWindow>().Value;
        shell.Show();
        return shell;
    }
}

向您的MainWindow添加Export属性。引导程序中的这一行需要:

var shell = container.GetExport<MainWindow>().Value;

[Export]
public partial class MainWindow : Window{}

现在剩下的就是运行引导程序:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        var bootstrapper = new MyBootstrapper();
        bootstrapper.Run();
    }
}

<强>更新

通过执行此处描述的示例,您可以很好地处理MEF:

https://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx

<强>更新

这是实现引导程序的一种更简洁的方法。

    public class MyBootstrapper : MefBootstrapper
    {
        protected override AggregateCatalog CreateAggregateCatalog()
        {
            return new AggregateCatalog();
        }

        protected override void ConfigureAggregateCatalog()
        {
            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(MyBootstrapper).Assembly));
        }      

        protected override CompositionContainer CreateContainer()
        {
            return new CompositionContainer(AggregateCatalog);
        }

        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
        }

        protected override DependencyObject CreateShell()
        {
            var shell = Container.GetExport<MainWindow>().Value;
            shell.Show();
            return shell;
        } 
    }