如何在MVVM应用程序中利用MEF? [英] How can I leverage MEF in my MVVM application?

查看:114
本文介绍了如何在MVVM应用程序中利用MEF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以使用mef和以下mvvm模式给我一个简单的wpf应用程序.我在互联网上看了很多东西,但发现的例子很少,而且这些例子很难理解.一些示例是wpf,mef,但不要遵循mvvm模式.

Can anybody give me a simple wpf application using mef and following mvvm pattern. I have looked a lot on the internet but i found very few examples and those example are very complex to understand. some examples are wpf, mef but dont follow mvvm pattern.

这就是我想要做的.

将有一个主要的wpf应用程序.这将加载所有模块(插件)并将其显示给用户.一个模块将包含2页或3页,以及下一个后退按钮(用于导航).现在,当我在主应用程序中选择一个模块时,该模块将打开,或者您可以说它替换了当前窗口,并且在按钮导航中它更改了该模块的视图.

There will a main wpf application. This will load all the modules (plugins) and show it to user. A module will contain 2 or 3 pages with next back buttons (used for navigation). Now when in main application i select a module, module opens or what you can say it replaces current window and on button navigation it changes views of the module.

主窗口->模块1->页面1

Main Window -> Module 1 -> Page 1

                       Page 2

                       Page 3

           Module 2 -> Page 1

                       Page 2

                       Page 3

所以现在看起来很干净.模块1是一个单独的项目,模块2是一个单独的项目.主窗口从dll读取模块并显示它们.单击模块将浏览其页面.

So it look clean now. Module 1 is a seperate project, module 2 is a seperate project. main window reads modules from dll and show them. clicking a module will go through its pages.

推荐答案

这些天我做了2个项目,这些项目都能满足您的需求.我所做的是建立一个主项目,该项目无非就是通过MEF收集模块并处理模块的选择.您还需要一个组件项目,在其中设置接口和导出属性.

i did 2 projects these days which do that what you want. what i have done is to set up a main project which does nothing more than collecting the modules via MEF and handle the selection of the module. you also need a component project where you set up the interfaces and export attributes.

此处有一些示例代码:

MainProject app.xaml.cs

MainProject app.xaml.cs

public partial class App : Application
{
    [ImportMany]
    private IEnumerable<Lazy<IComponent, IComponentMetadata>> _components;
    private CompositionContainer _mefcontainer;

    protected override void OnStartup(StartupEventArgs e)
    {
        ShutdownMode = ShutdownMode.OnExplicitShutdown;

        //i do login stuff here

        //i use task.factory here and dynamic splashscreen here

        this.MefContainer.ComposeParts(rahmen, this);

        foreach (var component in _components)
        {
            //check metadata and fill modules collection
        }

        //add modules collection to mainwindowviewmodel

         ShutdownMode = ShutdownMode.OnMainWindowClose;

         this.MainWindow.Show();

    }
}

Component.dll

Component.dll

public interface IComponent//Marker interface
{
    bool HasChanges { get; }
}

public interface IComponentMetadata
{
    string Displayname { get; }

    int SortIndex { get; }

    string ImagePath { get; }

    string IconPath { get; }
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ComponentExportAttribute : ExportAttribute, IComponentMetadata
{
    private const string DEFAULTICON = "pack://application:,,,/MyComponent;Component/Images/Default.png";


    public ComponentExportAttribute(string displayname, int sortindex): base(typeof(IComponent))
    {
        this.Displayname = displayname;
        this.SortIndex = sortindex;

        this.ImagePath = DEFAULTICON;
        this.IconPath = DEFAULTICON;
    }


    public ComponentExportAttribute(string displayname, int sortindex, string imagepath, string iconpath): base(typeof(IComponent))
    {
        this.Displayname = displayname;
        this.SortIndex = sortindex;

        this.ImagePath = String.IsNullOrWhiteSpace(imagepath) ? DEFAULTICON : imagepath;
        this.IconPath = String.IsNullOrWhiteSpace(iconpath) ? DEFAULTICON : iconpath;
    }

    #region Implementation of IComponentMetadata

    public string Displayname { get; private set; }

    public int SortIndex { get; private set; }

    public string ImagePath { get; private set; }

    public string IconPath { get; private set; }

    #endregion
}

模块示例

[ComponentExport("Test1",  150
    , "pack://application:,,,/TestProject;Component/Test/Logo1.png"
    , "pack://application:,,,/TestProject;Component/Test/Icon1.png")]
public partial class Test1MainWindow : UserControl, IComponent
{
    [ImportingConstructor]//if you want to do DI
    public Test1MainWindow ()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    #region Implementation of IComponent

    public bool HasChanges
    {
        get { return false; }
    }

    #endregion
}

或viewmodel export->(如果要执行此操作,则必须将数据模板导出到mainapp,如果需要,我可以显示此信息)

or viewmodel export --> (if you do this you have to export a datatemplate to the mainapp, i can show this if you want)

[ComponentExport("Test2", 500 
    , "pack://application:,,,/TestProject;Component/Test/Logo2.png"
    , "pack://application:,,,/TestProject;Component/Test/Icon2.png")]
public class Test2: INPCBase, IComponent
{

    [ImportingConstructor]
    public Test2()
    {
    }

    #region Implementation of IKabuComponent

    public bool HasChanges
    {
        get { return false; }
    }

    #endregion
}

这篇关于如何在MVVM应用程序中利用MEF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆