Long time no write blog, and today continue taking the time to write a series of articles MEF. Friends of the Park have made this series of articles is to be a directory, it looks easy, so I find time to do one, put the final of each article.
In front of four say the basics of MEF, finished school before four, more commonly used MEF has basically been finished, I believe we have been able to see the convenience brought by the MEF. MEF today to introduce some of the some of the more unusual things, the so-called more advanced usage that everyone talks about.
Speaking in front of Export Export annotations are added in each category above, to achieve export, is there a more convenient way to do that? The answer is yes, to write notes in the interface above, so long as the class that implements this interface will be exported, without having to write notes in each category above. Posted below only source interface and an implementation class, and the rest can imitate:
Interface code is as follows:
using System;
using System.Collections.Generic;
using System.Linq; using System.Text; using System.ComponentModel.Composition; namespace BankInterface { [InheritedExport] public interface ICard { //账户金额 double Money { get; set; } //获取账户信息 string GetCountInfo(); //存钱 void SaveMoney(double money); //取钱 void CheckOutMoney(double money); } }
Added [InheritedExport] mark above the interface, yes, this is the interface used in the above comments.
The following shows the code of an implementation class:
using System;
using System.Collections.Generic;
using System.Linq; using System.Text; using BankInterface; using System.ComponentModel.Composition; namespace BankOfChina { //[Export(typeof(ICard))] public class ZHCard : ICard { public string GetCountInfo() { return "Bank Of China"; } public void SaveMoney(double money) { this.Money += money; } public void CheckOutMoney(double money) { this.Money -= money; } public double Money { get; set; } } }
You can see, I commented out the export of annotations, running, still can be seen, or be derived such, the results of previous who saw already know.
Note: Although this method is relatively simple, but applies only to relatively simple applications, after reading the following, I believe we will be aware of his shortcomings.
The following enter today's focus:
MEF How to access a specific object
Earlier we said before, when derived, may be added in [the Export ()] annotations name identification, to identify a specific object, however, this method is only used for initialization of the page on the line filter, without introducing the open pages He could no longer imported, that we can not distinguish their differences in the collection of import, import all the classes are not identified.
To add identity to each class, we want to inherit ExportAttribute class, add the identity property MetaData for him, first of all to write inherited from ExportAttribute class code is as follows:
using System;
using System.Collections.Generic;
using System.Linq; using System.Text; using System.ComponentModel.Composition; namespace BankInterface { /// <summary> /// AllowMultiple = false,代表一个类不允许多次使用此属性 /// </summary> [MetadataAttribute] [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class ExportCardAttribute : ExportAttribute { public ExportCardAttribute() :base(typeof(ICard)) { } public string CardType { get; set; } } }
Code is very simple, the parent class constructor calls, declares a property CatdType, below an interface to add, modify ICard direct interface file, as follows:
using System;
using System.Collections.Generic;
using System.Linq; using System.Text; using System.ComponentModel.Composition; namespace BankInterface { public interface ICard { //账户金额 double Money { get; set; } //获取账户信息 string GetCountInfo(); //存钱 void SaveMoney(double money); //取钱 void CheckOutMoney(double money); } public interface IMetaData { string CardType { get;} } }
Has added interfaces IMetaData, only one property, to pay attention to this property and just wrote ExportCardAttribute class attribute names to be consistent, so as to achieve export.
Here with our ExportCardAttribute attribute to mark the class we want to export:
using System;
using System.Collections.Generic;
using System.Linq; using System.Text; using BankInterface; using System.ComponentModel.Composition; namespace BankOfChina { [ExportCardAttribute(CardType="BankOfChina")] public class ZHCard : ICard { public string GetCountInfo() { return "Bank Of China"; } public void SaveMoney(double money) { this.Money += money; } public void CheckOutMoney(double money) { this.Money -= money; } public double Money { get; set; } } }
Here, we can set CardType properties, different data types may be used depending on the circumstances.
Now, we modify the code for the main program:
the using the System;
the using the System.Collections.Generic; the using the System.Linq; the using the System.Text; the using the System.Reflection; the using the System.ComponentModel.Composition; the using System.ComponentModel.Composition.Hosting; the using BankInterface; namespace MEFDemo { class Program { // where AllowRecomposition = true indicates the operating parameters can be set in the recombinant member new member is fitted successfully [ImportMany (= AllowRecomposition. to true )] public the IEnumerable <Lazy <iCard, IMetaData Cards >> { GET; sET ;} static void Main ( String[] args) { Program pro = new Program(); pro.Compose(); foreach (var c in pro.cards) { if (c.Metadata.CardType == "BankOfChina") { Console.WriteLine("Here is a card of Bank Of China "); Console.WriteLine(c.Value.GetCountInfo()); } if (c.Metadata.CardType == "NongHang") { Console.WriteLine("Here is a card of Nong Ye Yin Hang "); Console.WriteLine(c.Value.GetCountInfo()); } } Console.Read(); } private void Compose() { var catalog = new DirectoryCatalog("Cards"); var container = new CompositionContainer(catalog); container.ComposeParts(this); } } }
Here I used the Lazy lazy loading mechanism (see in particular Lazy lazy loading ), we can see that we have access to CardType properties based on the properties of MetaData, to determine the type of Card, so as to distinguish the types of imported