如何在MVVM应用程序中利用MEF? [英] How can I leverage MEF in my MVVM application?
问题描述
任何人都可以使用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屋!