Overview
The purpose of this article is to briefly analyze and compare the MAF and MEF, and to give details of the MEF design and the details of the expansion, so that the reader can actually operate. Among them, the MAF design will be attached to my code, in fact, the official code I manually contact once, but still very fruitful, do not see the details of the hands-on, the MEF is my highlight, of course, Microsoft recommended solution, so this part of the content will be more.
As for why use MEF (plug-in framework) readers can analyze whether it is necessary to use it for their own projects.
The article inevitably has the insufficiency and the mistake, also invites everybody to be generous to point out, communicates with each other.
MAF and MEF
MAF is the framework of Microsoft integration in Framework3.5 to solve the plug-in programming, its advantages are rigorous but too rigid, the development speed is slow; MEF is a new addition in the Framework4.0, the potential goal is to replace MAF cumbersome and make development faster and suitable for most work scenarios, enhance ease of use.
The author of the following blog has been very comprehensive about this analysis, interested please refer to:
Http://www.cnblogs.com/techborther/archive/2012/02/06/2339877.html
Interface contract
Both the MAF and the MEF framework need an intermediate reference set-"contract", a digression, contract in the narrow sense is C # interface interface, in the broad sense will be a constraint, a few "parts" depend on the same convention to cooperate with each other, the coordination, This is the spiritual product of the mutual cooperation of human society. This kind of collaborative thinking is also applicable in the field of software, including service-oriented, interface-oriented design, plug-in design, code isolation and other ideas.
Code Analysis
First, define the contract layer: Define the method and the data interface, just declare the interface
namespacePRACTISE_MEF. contract{ Public InterfaceICalculator {string Calculate (string input); } Public InterfaceIOperation {intOperate (intLeftintRight ); } Public InterfaceIOperationData {Char Symbol {Get; } } Public Interfaceimultioperation {intmultioperate (PRACTISE_MEF. Core.Module.InputParams p); }}
View Code
Then, write the server-side (Host) parsing method: The server defines the Compositioncontainer object, which requires an add Category object, including the contract implementation method (MYCALCULATE) defined inside the program and an interface method in an external plugins directory.
namespacepractise_mef{ Public classMycalculateloader {PrivateCompositioncontainer _container; [Import (typeof(ICalculator))] PublicICalculator Calculator; PublicMycalculateloader () {//An aggregate catalog that combines multiple catalogs varCatalog =NewAggregatecatalog (); //Adds all the parts found in the same assembly as the program classCatalog. Catalogs.add (NewAssemblycatalog (typeof(mycalculate). Assembly)); Catalog. Catalogs.add (NewDirectorycatalog (@". .. \output\plugins\")); //Create the Compositioncontainer with the parts in the catalog_container =Newcompositioncontainer (catalog); //Fill The Imports of this object Try { This. _container.composeparts ( This); } Catch(Compositionexception compositionexception) {Console.WriteLine (Compositionexception.tostri Ng ()); } } }}
View Code
Next, implement Mycalculate contract method, algorithm:
namespacepractise_mef{ Public classmycalculate {[Export (typeof(ioperation))] [ExportMetaData ("Symbol",'+')] Public classadd:ioperation { Public intOperate (intLeftintRight ) { returnLeft +Right ; }} [Export (typeof(ioperation))] [ExportMetaData ("Symbol",'-')] Public classsubtract:ioperation { Public intOperate (intLeftintRight ) { returnLeft-Right ; } } }}
View Code
Then, in this assembly process the plug-in group method: called the plug-in group is because there may be many plug-in methods in the System container, need to differentiate the application of the plug-in or all according to business requirements, where operations is the system automatically imported the current loaded plug-in method collection.
namespacepractise_mef{[Export (typeof(ICalculator))] Public classMycalculateadapter:icalculator {[ImportMany] IEnumerable<lazy<ioperation, ioperationdata>>operations; Publicstring Calculate (String input) {intLeft ; intRight ; Char operation; intfn = findfirstnondigit (input);//finds the operator if(FN <0)return "Could not the parse command."; Try { //separate out the operandsleft =int. Parse (input. Substring (0, FN)); Right=int. Parse (input. Substring (Fn +1)); } Catch { return "Could not the parse command."; } Operation=INPUT[FN]; foreach(Lazy<ioperation, ioperationdata> iinchoperations) { if(I.metadata.symbol.equals (operation))returnI.value.operate (left, right). ToString (); } return "Operation not found!"; } Private intFindfirstnondigit (String s) { for(inti =0; i < s.length; i++) { if(! (Char.isdigit (S[i])))returni; } return-1; } }}
View Code
Finally, in writing the extended plug-in method:
namespacePRACTISE_MEF. plugin.calculateex{/// <summary> ///Mod/// </summary>[System.ComponentModel.Composition.Export (typeof(PRACTISE_MEF. contract.ioperation)] [System.ComponentModel.Composition.ExportMetadata ("Symbol",'%')] Public classCALCULATEMOD:PRACTISE_MEF. contract.ioperation { Public intOperate (intLeftintRight ) { returnLeft%Right ; } }}
At this point, a simple, complete plug-in application has been completed, can achieve dynamic loading processing 2 digital algorithm (take the remainder), when the software needs to dynamically increase the function, only the sequence of writing XxxxEx.dll, and then copy to the software plugins directory, the software will dynamically add functionality. In contrast, the MEF hides and simplifies more operations, allowing the user to complete the software plug-in and make the project more flexible by simply completing a few steps on demand.
Project configuration
Create a new output folder on a disk, and create a new plugins folder in the output directory with the name fixed, changing the code in the project to modify the name, unlike the MAF conventions.
- PRACTISE_MEF project configuration
2. Practise_mef. Contract project configuration
3.practise_mef. Core project configuration
4.practise_mef. Plugin.calculateex project configuration
You need to add a project reference PRACTISE_MEF in your project. Contract.dll, its property is set to Copy Local to False remember.
The same output directory is \output\plugins\, after setting the property, Practise_mef. Contract.dll will not be exported together to the plugins directory, and the constraint uses PRACTISE_MEF. Plugin.CalculateEx.dll in the project to ensure that there is Contact.dll.
Sample code Download
Reference
MAF and MEF differences: http://www.cnblogs.com/techborther/archive/2012/02/06/2339877.html
MEF Official explanation: Http://msdn.microsoft.com/en-us/library/dd460648.aspx
MEF Analysis: http://www.360doc.com/content/11/0830/16/7582031_144521508.shtml
Refactoring Notes---MEF framework (top)