MEF:在我的UserControls中创建一个ViewModel

时间:2016-05-25 19:44:21

标签: c# wpf mvvm mef

我目前正在将我的WPF / MVVM应用程序从Ninject转换为MEF,以利用一些插件架构。没有棱镜或团结,我也不想走那条路。我使用VS2015和.Net 4.6。

我使用的是MVVM Light流行的技术,你可以使用Ninject在XAML中实例化ViewModel。

  public static ImageViewModel ImageVM => Kernel.Get<ImageViewModel>();

但是现在我要转移到MEF,我想看看是否有其他选择。 Stack Exchange上目前已回复的大多数帖子都相当陈旧,我希望现在有一些新的替代品可用.NET 4.5。

TL;博士

我有一个包含10个UserControl的窗口。每个用户控件都附加了一个ViewModel的新实例。由于窗口是在xaml中创建用户控件,如何将ViewModel的唯一实例添加到每个控件中?

public partial class FingerprintControl{

    public FingerprintControl() {
        InitializeComponent();
    }

    [Import]
    public FingerprintControlViewModel ViewModel
    {
        get { return DataContext as FingerprintControlViewModel; }
        set { DataContext = value; }
    }

我看到的一条建议说要添加

    CompositionInitializer.SatisfyImports(this);

在InitializeComponent()之后。但这只是一个Silverlight类。

我查看了https://www.nuget.org/packages/Microsoft.Composition/,但MEF 2的文档在网站上几乎不存在。

我还看到ExportFactory被添加到MEF 2中,但不确定这是否有帮助。

我确实在MEF 2中找到了静态方法 CompositionContextExtensions.SatisfyImports ,但我不知道如何处理它。文档只说,&#34;满足指定上下文中指定对象的导入。&#34; (不是真正有用的......)

1 个答案:

答案 0 :(得分:1)

我们为所有应用程序使用静态方法为Mef使用类包装器:

public class Mef
{
    private static CompositionContainer container = null;
    public static CompositionContainer Container { get { return container; } }

    private static AggregateCatalog catalog;

    public static void Initialize()
    {
        catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new DirectoryCatalog(path: ".", searchPattern: "*.exe"));
        catalog.Catalogs.Add(new DirectoryCatalog(path: ".", searchPattern: "*.dll"));
        container = new CompositionContainer(catalog);
        StartWatch();
    }

    private static void StartWatch()
    {
        var watcher = new FileSystemWatcher() { Path = ".", NotifyFilter = NotifyFilters.LastWrite };
        watcher.Changed += (s, e) =>
        {
            string lName = e.Name.ToLower();
            if (lName.EndsWith(".dll") || lName.EndsWith(".exe"))
                Refresh();
        };
        watcher.EnableRaisingEvents = true;
    }

    public static void Refresh()
    {
        foreach (DirectoryCatalog dCatalog in catalog.Catalogs)
            dCatalog.Refresh();
    }
}

(注意:我们使用上述内容根据用户的要求动态地将插件加载到我们的应用程序中。您可能希望使用不同的目录系统 - 有几个可供选择)

然后我们在app生命周期的早期初始化类,通常是在App.Xaml代码隐藏构造函数中:

    public App()
    {
        this.InitializeComponent();
        Mef.Initialize();
    }

当我有基类mef-import时,在类/代码隐藏构造函数中调用:

Mef.Container.SatisfyImports(this);

希望这有帮助。