Coproject - a RIA Caliburn.Micro demo, part 5
2015-09-03 06:49
381 查看
In this part, we will add some module metadata. Note that you can get the most recent Coproject source codes from itsCodeplex site.
As you probably noticed, modules are not loaded into shell in any specified order. And since we don’t want the modules be in arbitrary order, we need to add some metadata. You can read more about MEF metadata here.
The easiest way is to use ExportMetadataAttribute. We would update HomeViewModel as:
and the other ViewModels in the same manner. Next, must update ShellViewModel constructor. Instead of IModule directly, we will request Lazy<IModule, IModuleMetadata> from MEF. This will make MEF to provide lazy reference to requested instance and also metadata
of type IModuleMetadata. You might read an introduction to Lazy here.
Let’s create IModuleMetadata in new folder /Framework/:
Finally, ShellViewModel’s constructor:
The code should be self-describing. Now, run the application. You may experiment with order numbers and see that the order in application menu changes respectively.
Although this solution works, you probably don’t like the idea of writing magic strings like “Order”. So we should make these metadata strongly typed. To do this, add new class ExportModuleAttribute to the Framework folder. Application structure should look
like this:
![](http://www.baud.cz/Media/Windows-Live-Writer/Coproject---a-RIA-Cali.Micro-demo-part-5_B979/image_thumb_2.png)
Add this implementation of the created class:
As you can see, we simply extend the original ExportAttribute to accept order integer. In this case, we can add default export type (IModule). The first attribute [MetadataAttribute] is very important because it tells MEF to also load metadata from ExportModuleAttribute.
Finally, we can merge the two attributes on each module viewmodel:
into one:
Do this for all module view models and run the application.
Talking about MEF exports, you might wonder what happens when you import a component more than once – will MEF provide you the same instance or will it create a new one? The answer is: It depends on configuration. You can specify this behavior on the places.
Either on export:
Or on import:
CreationPolicy enum has three options:
Shared – MEF will return always the same instance (singleton pattern)
NonShared – MEF will always create a new instance
Any – not specified, depends on the other side of contract (export/import). This is default and if not set to other, this will act as Shared by default.
You can read more about this topic here. I suggest reading whole series MEF
for Beginner or MEF Programming Guide.
Metadata
As you probably noticed, modules are not loaded into shell in any specified order. And since we don’t want the modules be in arbitrary order, we need to add some metadata. You can read more about MEF metadata here.The easiest way is to use ExportMetadataAttribute. We would update HomeViewModel as:
[Export(typeof(IModule))] [ExportMetadata("Order", 10)] public class HomeViewModel : Screen, IModule
and the other ViewModels in the same manner. Next, must update ShellViewModel constructor. Instead of IModule directly, we will request Lazy<IModule, IModuleMetadata> from MEF. This will make MEF to provide lazy reference to requested instance and also metadata
of type IModuleMetadata. You might read an introduction to Lazy here.
Let’s create IModuleMetadata in new folder /Framework/:
namespace Coproject.Framework { public interface IModuleMetadata { int Order { get; } } }
Finally, ShellViewModel’s constructor:
[ImportingConstructor] public ShellViewModel([ImportMany]IEnumerable<Lazy<IModule, IModuleMetadata>> moduleHandles) { var modules = from h in moduleHandles orderby h.Metadata.Order select h.Value; Items.AddRange(modules); }
The code should be self-describing. Now, run the application. You may experiment with order numbers and see that the order in application menu changes respectively.
Strongly typed metadata
Although this solution works, you probably don’t like the idea of writing magic strings like “Order”. So we should make these metadata strongly typed. To do this, add new class ExportModuleAttribute to the Framework folder. Application structure should looklike this:
![](http://www.baud.cz/Media/Windows-Live-Writer/Coproject---a-RIA-Cali.Micro-demo-part-5_B979/image_thumb_2.png)
Add this implementation of the created class:
[MetadataAttribute] [AttributeUsage(AttributeTargets.Class)] public class ExportModuleAttribute : ExportAttribute, IModuleMetadata { public int Order { get; private set; } public ExportModuleAttribute(int order) : base(typeof(IModule)) { Order = order; } }
As you can see, we simply extend the original ExportAttribute to accept order integer. In this case, we can add default export type (IModule). The first attribute [MetadataAttribute] is very important because it tells MEF to also load metadata from ExportModuleAttribute.
Finally, we can merge the two attributes on each module viewmodel:
[Export(typeof(IModule))] [ExportMetadata("Order", 10)]
into one:
[ExportModule(10)] public class HomeViewModel : Screen, IModule
Do this for all module view models and run the application.
PartCreationPolicy
Talking about MEF exports, you might wonder what happens when you import a component more than once – will MEF provide you the same instance or will it create a new one? The answer is: It depends on configuration. You can specify this behavior on the places.Either on export:
[ExportModule(10)] [PartCreationPolicy(CreationPolicy.NonShared)] public class HomeViewModel : Screen, IModule
Or on import:
[Import(typeof(IShell), RequiredCreationPolicy=CreationPolicy.Shared)] public IShell Shell { get; set; }
CreationPolicy enum has three options:
Shared – MEF will return always the same instance (singleton pattern)
NonShared – MEF will always create a new instance
Any – not specified, depends on the other side of contract (export/import). This is default and if not set to other, this will act as Shared by default.
You can read more about this topic here. I suggest reading whole series MEF
for Beginner or MEF Programming Guide.
相关文章推荐
- Coproject - a RIA Caliburn.Micro demo, part 6
- Coproject - a RIA Caliburn.Micro demo, part 7
- Coproject - a RIA Caliburn.Micro demo, part 8
- Coproject - a RIA Caliburn.Micro demo, part 9
- Coproject - a RIA Caliburn.Micro demo, part 10
- Coproject - a RIA Caliburn.Micro demo, part 11
- 我是如何利用1条百度知道给网站日引流破万的?
- Coproject - a RIA Caliburn.Micro demo, part 10.5
- Coproject - a RIA Caliburn.Micro demo, part 12
- Coproject - a RIA Caliburn.Micro demo, part 14
- Coproject - a RIA Caliburn.Micro demo, part 13
- Nginx 配置常见误区
- Linux学习之grep篇
- Hadoop学习计划
- Clustered Shading架构实现步骤
- wcf利用IDispatchMessageInspector实现接口监控日志记录和并发限流
- Nginx的作用
- centos7关闭防火墙
- hadoop学习(一)-- centos 64位编译安装hadoop
- nginx完美支持thinkphp3.2.2