Managed extensibility framework (MEF) is a new feature in. Net 4.0. It is a lightweight framework that can be automatically expanded. The following is the original version of msdn.
Assume that you are a large-scale application that must provide scalability support.Program. Your application must contain a large number of small components that may be required and be responsible for creating and running these components.
The simplest way to solve this problem is to use these componentsSource codeIncluded in your application, and thenCodeCall them directly. This practice has many obvious defects. Most importantly, you cannot add new components without modifying the source code. This restriction may be accepted by Web applications (for example, but it does not work in client applications. You may not have access to the source code of the component because these components may be developed by a third party for the same reason, you do not allow third parties to access your code.
A slightly more complex method is to provide an extension point or interface that allows applications to be separated from their components. Based on this model, you may provide an interface that can be implemented by a component and an API to enable the interface to interact with your application. This method can solve the problem that requires source code access, but it still has its own difficulties.
Because the application lacks the ability to discover its own components, it must still clearly inform the application of which components are available and should be loaded. This is usually done by explicitly registering available components in a configuration file. This means that ensuring that the components are correct becomes a daily maintenance problem, especially when the end user rather than the developer executes the update operation.
In addition, components cannot communicate with each other unless they are strictly defined by the application itself. If the application architect does not predict that a communication is required, the corresponding communication is usually not allowed.
Finally, component developers have to rely heavily on the Assembly containing the interfaces they implement. In this way, it is difficult to use the same component in multiple applications. In addition, problems may occur when creating a test framework for the component.
In the absence of MEF, reflection is usually used to complete component registration. reflection has many inconveniences. the application needs to know the namespace and Assembly address. If a new component is registered, developers or dedicated maintenance personnel usually need to add new configurations in the configuration file. worse, you may need to modify the code.
MEF can manage the updated Assembly through the automatic discovery mechanism, without the involvement of professional personnel. It can easily complete the automatic update and upgrade of software.
The following code demonstrates the use of MEF and must be referencedSystem. componentmodel. Composition. dllAndSystem. Data. datasetextensions. dll
Using System; Using System. Collections. Generic; Using System. LINQ; Using System. text; Using System. componentmodel. composition; Using System. componentmodel. Composition. Hosting;Namespace Simplecalculator3 { // Operation expression Public Interface Icalculator {string calculate (string input );} // Left and right participants Public Interface Ioperation { Int Operate ( Int Left, Int Right );} // Operator Public Interface Ioperationdata {char symbol { Get ;}} // The metadata of each operation indicates the symbols of the corresponding operation, such as +,-, and. // To make addition operations available, add the following classes to the module or simplecalculator namespace. // Exportattribute features have the same functions as before. The exportmetadataattribute feature attaches metadata to the corresponding export in the form of name/value pairs. // Although the add class can implement ioperation, the class implementing ioperationdata is not explicitly defined. // Conversely, MEF implicitly creates a class using attributes based on the provided metadata name. (This is one of the methods to access metadata in MEF .) // The combination in MEF is recursive. You explicitly combine the program object, which imports an icalculator that proves to be of the mysimplecalculator type. // Next, mysimplecalculator imports the set of ioperation objects, // The import will be filled with the import of program when mysimplecalculator is created. // If the add class declares further import, you must also fill in the next import, and so on. // Any unfilled import will cause a combination error. (However, you can declare the import as optional or assign default values to it .) [Export ( Typeof (Ioperation)] [exportmetadata (" Symbol ", '+')] Class Add: ioperation { Public Int Operate ( Int Left, Int Right ){ Return Left + right;} [Export ( Typeof (Ioperation)] [exportmetadata (" Symbol ", '-')] Class Subtract: ioperation { Public Int Operate ( Int Left, Int Right ){ Return Left-right;} [Export ( Typeof (Icalculator)] Class Mysimplecalculator: icalculator { // To make simplecalculator scalable, it needs to import a set of operations. Generally, the importattribute feature is filled with only one exportattribute. // If multiple exports are available, the combined engine generates an error. // You can use the importmanyattribute feature to create an import that can be filled with any number of exported data. [Importtasks] // Lazy (of T, tmetadata) is a type provided by MEF to save indirect references to export. // In addition to the exported object, you can also obtain the exported metadata or description of the exported object. // Each lazy (of T, tmetadata) contains an ioperation object (representing an actual operation) and an ioperationdata object (representing the metadata of the operation ). Ienumerable <lazy <ioperation, ioperationdata> operations; Public String calculate (string input ){ Int Left; Int Right; char operation;Int Fn = findfirstnondigit (input ); // Finds the operator If (FN <0) Return " Cocould not parse command. "; Try { // Separate out the operands // Analyze the input string as the left and right operands and operators in the initial step. Left = Int . Parse (input. substring (0, FN); Right = Int . Parse (input. substring (FN + 1 ));}Catch { Return " Cocould not parse command. ";} Operation = input [FN]; // In the foreach loop, each member of the operations set is checked. // The object types are lazy (of T, tmetadata). You can use the metadata attribute and value attribute to access its metadata value and the exported object respectively. // In this example, if the symbol attribute of the ioperationdata object is found to be a match, the calculator calls the operate method of the ioperation object and returns the result. Foreach (Lazy <ioperation, ioperationdata> I In Operations ){ If (I. Metadata. symbol. Equals (operation ))Return I. value. Operate (left, right). tostring ();} Return " Operation not found! ";} Private Int Findfirstnondigit (string s ){ For ( Int I = 0; I <S. length; I ++ ){ If (! (Char. isdigit (s [I]) Return I ;} Return -1 ;}}Class Program { Private Compositioncontainer _ container; [import ( Typeof (Icalculator)] Public Icalculator calculator; Private Program (){ // To discover the parts that can be used to combine containers, the combined container uses the "directory ". // A directory is an object through which available components can be generated from some sources. // MEF provides a directory for discovering components from the provided type, assembly, or directory. // Application developers can easily create a new directory for discovering components from other sources (such as Web Services. // An aggregate catalog that combines multiple catalogs VaR catalog =New Aggregatecatalog (); // Adds all the parts found in the same assembly as the program class Catalog. Catalogs. Add ( New Assemblycatalog ( Typeof (Program). Assembly); Catalog. Catalogs. Add ( New Directorycatalog (" E: \ Temp ")); // Create the compositioncontainer with the parts in the catalog _ Container = New Compositioncontainer (Catalog ); // Fill the imports of this object Try { This . _ Container. composeparts ( This );} Catch (Compositionexception) {console. writeline (compositionexception. tostring ());}} Static Void Main ( String [] ARGs) {program P = New Program (); // Composition is saved med in the constructor String s; console. writeline ("Enter command: "); While ( True ) {S = console. Readline (); console. writeline (P. Calculator. Calculate (s ));}}}}
Extended simplecalculator
Create a project whose output type is class library and add the following code
UsingSystem;UsingSystem. Collections. Generic;UsingSystem. LINQ;UsingSystem. text;UsingSystem. componentmodel. composition;NamespaceExtendedoperations {[Export (Typeof(Simplecalculator3.ioperation)] [exportmetadata ("Symbol", '%')]Public ClassMoD: simplecalculator3.ioperation {Public IntOperate (IntLeft,IntRight ){ReturnLeft % right ;}}}
after compilation, copy the generated DLL file to the E: // temp directory and run the first project. You can test the % operation of the extension.