The previous study of the basic knowledge of the MEF, wrote a simple demo, followed by the content of the previous article to continue to learn, if not read the previous article,
Let's take a look at the import and export in MEF, or the code in the previous article (I'll post the complete code in this article), and modify the program's code as follows:
Using System;Using System.Collections.Generic;Using System.Linq;Using System.Text;Using System.Reflection;Using System.ComponentModel.Composition;Using System.ComponentModel.Composition.Hosting;Namespace mefdemo{ Class Program{ [Import ("Musicbook")] Public Ibookservice Service {GetSet } Staticvoid Main (String[] args) { Program Pro =New program (); Pro.compose (); if (pro. Service! =Null { Console.WriteLine (Pro. Service.getbookname ()); } Console.read (); } private void Compose () { var catalog = new assemblycatalog (assembly.getexecutingassembly ()); Span class= "indent" > Compositioncontainer container = new compositioncontainer (catalog); container. Composeparts (this); }}} /span>
The code to modify Musicbook is as follows:
Using System;Using System.Collections.Generic;Using System.Linq;Using System.Text;Using System.ComponentModel.Composition;Namespace mefdemo{ [Export ( "Musicbook", typeof (ibookservice))]< Span class= "indent" > public class musicbook:ibookservice { public string bookname {get; set;} public string getbookname ( ) { return "musicbook"; }}} /span>
Note that the red is the changed place, the code in other places has not changed, the last time we used the export method is [Export (typeof (Ibookservice))] , this time one more parameter, yes, this is a contract name, The name can be casually up, and can be repeated, but if the name disorderly, and other DLLs in the repetition, it will lead to a lot of bugs in the program, it is best to follow certain specifications to the name.
There is a contract name, the contract name to be specified when importing (import), otherwise you will not be able to find musicbook,export another method is [Export ("name")], This method only specifies the contract name, does not specify the export type, Then the default export type is the object type, and the objects exported to the import will be of the type of the class, otherwise it won't match the component.
Until now, we have only written an interface and an implementation class, the export is also a class, the following we add a few more classes to see what will happen, in order to facilitate the test, I put the implementation of the interface class in a file, after adding several classes, the Musicbook class file code is as follows:
Using system;using system.collections.generic;using system.linq;using system.text;using System.componentmodel.composition;namespace mefdemo{[Export ("Musicbook ", typeof (Ibookservice))]PublicClass Musicbook:ibookservice{ public string BookName {get; set;} public string Getbookname () { Return"Musicbook "; }}[Export ("Musicbook ", typeof (Ibookservice))]PublicClass Mathbook:ibookservice{ public string BookName {get; set;} public string Getbookname () { Return"mathbook "; }} [Export ( "musicbook", typeof (Ibookservice))] public class historybook:ibookservice { Span class= "indent" > public string BookName {get; set;} public string getbookname () { return "historybook"; }}} /span>
Here add two classes, Historybook and Mathbook, all inherit from Ibookservice interface, note that their contract name is the same, all for Musicbook, and then in detail this problem, the revised program code is as follows:
Using System;Using System.Collections.Generic;Using System.Linq;Using System.Text;Using System.Reflection;Using System.ComponentModel.Composition;Using System.ComponentModel.Composition.Hosting;Namespace mefdemo{ Class Program{[ImportMany ("Musicbook")] Public ienumerable<ibookservice> Services {GetSet } Staticvoid Main (String[] args) { Program Pro =New program (); Pro.compose (); if (pro. Services! =Null { foreach (var sIn Pro. Services) { Console.WriteLine (S.getbookname ()); } } Console.read (); } private void Compose () { var catalog = new assemblycatalog (assembly.getexecutingassembly ()); Span class= "indent" > Compositioncontainer container = new compositioncontainer (catalog); container. Composeparts (this); }}} /span>
It is important to note that the two lines of red code, [ImportMany ("Musicbook")] and the following declaration becomes IENUMERABLE<>, because to export multiple instances, so to use the collection, the following using the foreach traversal output, The results of the operation are as follows:
A total of three, all output, right! is not very useful ah, haha ~ ~
Of course, if you want to output all of them, you can export them all without writing the contract name when you import and export it in the first article. So what are the benefits of writing a contract name?
Here we use code to illustrate the problem, modify the implementation of the contract name of the class as follows:
Using system;using system.collections.generic;using system.linq;using system.text;using System.componentmodel.composition;namespace mefdemo{[Export ("Musicbook ", typeof (Ibookservice))]PublicClass Musicbook:ibookservice{ public string BookName {get; set;} public string Getbookname () { Return"Musicbook "; }}[Export ("Mathbook", typeof (Ibookservice))]PublicClass Mathbook:ibookservice{ public string BookName {get; set;} public string Getbookname () { Return "mathbook"; }} [Export ( public class historybook:ibookservice { Span class= "indent" > public string BookName {get; set;} public string getbookname () { return "historybook"; }}} /span>
Now the contract names of the three classes are different, the other code does not move, run the program again to see if it is now only output musicbook, similarly, modify [Import ("name")] in the contract name, will be imported to specify the name of the class, the contract name can be repeated, since the We can classify the class with a contract name, which can be imported according to the contract name.
Note : The type in ienumerable<t> must match the export type of the class, as the class labeled [Exprot (typeof (Object)]), then it must be declared as Ienumerable<object > can match to the exported class.
For example: We mark [Export ("book")] on the class, we only specify the contract name, but not the type, then the default is object, at this time also use ienumerable<ibookservice> to match.
So, this is the case when the output is a forced type conversion, the code is as follows:
[Export ("Musicbook")] classMusicbook:ibookservice {public string BookName {get; set;} Public string Getbookname () {"musicbook"; } }
The code in program changes as follows:
Using System;Using System.Collections.Generic;Using System.Linq;Using System.Text;Using System.Reflection;Using System.ComponentModel.Composition;Using System.ComponentModel.Composition.Hosting;Namespace mefdemo{ Class Program{ [ImportMany ("Musicbook ")] Public ienumerable<Object> Services {GetSet } Staticvoid Main (String[] args) { Program Pro =New program (); Pro.compose (); if (pro. Services! =Null { foreach (var sIn Pro. Services) { var ss = (Ibookservice) s; Console.WriteLine (ss. Getbookname ()); } } Console.read (); } private void Compose () { var catalog = new assemblycatalog (assembly.getexecutingassembly ()); Span class= "indent" > Compositioncontainer container = new compositioncontainer (catalog); container. Composeparts (this); }}} /span>
This will work properly ~ ~
C # Extensible Programming MEF Learning Note (ii): MEF Export and Import