C # Programming Scalable MEF study notes (five): MEF Advanced Advanced

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:

Copy the code
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); } }
Copy the code

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:

Copy the code
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; } } }
Copy the code

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:

Copy the code
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; } } }
Copy the code

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:

Copy the code
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;} } }
Copy the code

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:

Copy the code
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; } } }
Copy the code

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:

Copy the code
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); } } }
Copy the code

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

Guess you like

Origin www.cnblogs.com/ljdong7/p/12107732.html