C # Extensible Programming MEF Learning Note (V): MEF Advanced Step

Source: Internet
Author: User

Long time no blog, and today to continue to write the MEF series of articles. A friend of the park put forward this series of articles to do a directory, it seems convenient, so the time to do a, put to the end of each article.

The first four of the basic knowledge of MEF, learned the top four, the MEF is more commonly used in the basic has been finished, I believe you can see the convenience of MEF. Today, we introduce some of the less common things in MEF, the so-called more advanced usage of what we are saying.

The previous export is to add export annotations on each class to achieve the exported, then is there a more convenient way? The answer is to write annotations on the interface so that classes that implement the interface will be exported without having to write annotations on each class. The following only the interface and an implementation class source code, the rest of the imitation can:

The 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   {      //Account amount      double money {get; set;}      Get account information      string Getcountinfo ();      Deposit      void Savemoney (double money);      Withdraw Money      void Checkoutmoney (double);   }}

The [InheritedExport] tag is added to the interface, yes, this is the annotation used on the interface.

Here's the code for 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;}}   }

As you can see, I commented out the exported annotations, after running, still can see, this class is still exported, the results of the operation is believed to have read the previous article has been known.

Note: Although this method is relatively simple, but only for a relatively simple application, after reading the following, I believe you will be aware of his shortcomings.

Here's the key to today:

How to access a specific object in the MEF

As we said earlier, in the export, you can include the name identification in the [Export ()] annotation to identify a specific object, but this method is only used for page initialization when the line filter, the page opened after the import is no longer imported, That means we can't distinguish between the imported collections, all the imported classes are not identified.

In order to add an identity to each class, we will inherit the Exportattribute class, add the identity attribute metadata for him, first write the class that inherits from Exportattribute, the 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, Represents a class that does not allow multiple use   of this property   //</summary> [Metadataattribute]   [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] public   class Exportcardattribute:exportattribute   {public      exportcardattribute ()         : Base (typeof (ICard))      {      } public      string Cardtype {get; set;}}}   

The code is simple, call the constructor of the parent class, declare a property catdtype, the following to add an interface, directly modify the Icard interface file, the code is as follows:

Using system;using system.collections.generic;using system.linq;using system.text;using System.componentmodel.composition;namespace bankinterface{Public   interface ICard   {      //account amount      Double Money {get; set;}      Get account information      string Getcountinfo ();      Deposit      void Savemoney (double money);      Take money      void Checkoutmoney (double);   }   Public interface Imetadata   {      string Cardtype {get;}}   }

Add the interface Imetadata, there is only one property, note that this property should be consistent with the name of the property in the Exportcardattribute class just written, in order to achieve the export.

The following uses our Exportcardattribute property to mark the classes 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 the properties of the Cardtype, and can use different data types depending on the situation.

Now, we modify the main program code to:

Using system;using system.collections.generic;using system.linq;using system.text;using System.Reflection;using System.componentmodel.composition;using system.componentmodel.composition.hosting;using BankInterface;namespace      Mefdemo{class Program {//Where the Allowrecomposition=true parameter represents the reorganization of the part set that runs when a new part is successfully assembled.      [ImportMany (Allowrecomposition = true)] public 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") {Con Sole.               WriteLine ("Here is a card of the Bank of China");            Console.WriteLine (C.value.getcountinfo ()); } if (C.metadata.cardtype = = "Nonghang") {Console.WriteLine ("Here is a card of Nong Y               E 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 delay loading mechanism (see lazy delay loading for details), and we can see that we can determine the type of the card by accessing the Cardtype property based on the metadata property, thus distinguishing the type of the import.

Click here to download the source code.

C # Extensible Programming MEF Learning Note (V): MEF Advanced Advance (GO)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.