Transferred from: http://developer.51cto.com/art/201104/255455_all.htm
. NET is the Microsoft XML Web services platform. MEF is an important library of the. NET Framework 4.0, and the extended support for Visual Studio Code Editor is also built on MEF. Let's see it together.
MEF (Managed Extensibility Framework) is an important library of the. NET Framework 4.0, and the extended support for Visual Studio Code Editor is also built on MEF . The goal of MEF is to simplify the creation of extensible applications whose core class is Composablepart, which is a component with the ability to assemble, each of which is called a composablepart (Chinese can be a composable component, although the following is always used in English, so the more appropriate) components can be combined ( Called import) the functionality of other components (other components provide functionality by declaring export) and it can also expose its functionality to other components by defining export. Composablepart through the component catalog (Composablepartcatalog) to search for the functionality that is needed, the component directory can be a physical file directory, networked storage, and so on. Each composablepart also has the ability to combine dynamically, which can be re-assembled if necessary. This article will use the bottom-up approach to experience the MEF design ideas.
1 , no nonsense MEF
The core of MEF is the Composable component Composablepart, which is described and created by Composablepartdefintion. Each composable component provides functionality to other components by defining exportdefintion, and by importdefinition referencing the functionality of other components, metadata to describe the information of the component itself. After you create a Composablepart component, you implement the component combination by searching for the required functionality in the component catalog (Composablecatalog).
2 , a typical MEF composition process
(1) Creating a component directory (such as Assemblycatalog)
(2) Create a composite container compositioncontainer, component container through component Catalog Search component definition
(3) Create a component Composablepart
(4) Get the definition of other component functions from the component container, then perform the matching combination
The sample code is as follows:
var New // Create an assembly directory to get all the component definitions from an assembly var New // Create a composite container var New mycomponent (); // perform a combination, get exportdefinition from the container, and create instances to group together //
The principle is as follows (from Mef.codeplex.com official website):
3 MEF Essence--Combinatorial primitives
A composite primitive is an "essential" support for providing an extensible, composable component, which is at the very bottom of the MEF and is the core class of the entire framework, consisting of 6 classes, as shown in the MEF white Paper, which is a bit abstract, but looks very enjoyable, with the Chinese version of my translation attached.
The composition primitive classes are described as follows:
(1) Composablepart: You can combine components, which is the core class of a composite primitive. Exportdefinitions represents the description of the functionality provided by the component, while Importdefinitions is a description of the constraints that reference the functionality of other components. Metadata is a special identifier for the component itself, and when a Composablepart references other component functions through import, the metadata may be a condition that satisfies the constraints of the reference function.
(2) Exportdefinition: Defines the functionality that Composablepart provides to other components, which is described using a contractname and metadata. Contractname is the contract that uses this function, metadata is used to further describe this function.
(3) Importdefinition: Defines the Composablepart reference to the functionality provided by other components, that is, a exports that references another component. Importdefintion uses an expression to describe the constraint, which is defined in the constraint property, and its type is expression>. This expression is used to make a matching decision for a exportdefintion, which matches the following method:
Here is the code snippet:
var allexportdefs = ... // get all exportdefinition from Composablepartcatalog var // a proxy compiled into a matching function var // Use the proxy of the matching function to filter all the Exportdefs
(4) Composabledefinition: The Composablepart definition is the factory of Composablepart, which defines a class of Composablepart-referenced functions, exposed features, and their own meta-data. The referenced functionality is described in Importdefinitions, and the exposed functionality is described by exportdefinitions. While metadata is a description of the component itself, it is commonly used in MEF to determine whether to combine the functionality provided by another component by matching the metadata of another component when one component references (Import) another component's functionality. This class is the factory of Composablepart and provides the CreatePart method.
(5) Composablepartcatalog: Composable component catalogs, which are used to discover components that may come from physical directories, networked storage, and so on.
4 , how to use MEF
On top of that, we describe the core of MEF-the composition primitive, which sounds simple and easy to understand, but it is not so easy to write a composablepartdefinition directly using a composite primitive, and in the implementation of MEF, these classes are abstract classes. A model used to describe the entire extensible framework. I don't want to talk about how the MEF is going to use a composite primitive, so let's look at the example.
4.1 define Composablepartdefinition
MEF simplifies the definition of Composablepart by introducing an attribute-based programming model, as shown in the Messagesender and processor classes are composablepart definitions.
here is the code snippet:
Public classMessagesender {[Export ("Messagesender")] Public voidSend (stringmessage) {Console.WriteLine (message); }} [Export] Public classProcessor {[Import ("Messagesender")] PublicAction Messagesender {Get;Set; } Public voidSend () {Messagesender ("processed"); } }
4.2 , create Composablepart
Here is the code snippet:
varCatalog =NewAssemblycatalog (assembly.getexecutingassembly ());//Create an assembly directory to get all the component definitions from an assemblyvarAssemblycatalog =NewAssemblycatalog (assembly.getexecutingassembly ());//Creating a Component Catalogvarcontainer =NewCompositioncontainer (Assemblycatalog);//Creating a composite containervarProcessorpart =NewProcessor (); Container.composeparts (Processorpart); //Execution CombinationProcessorpart.send (); Console.ReadLine ();
4.3 , the nature of the feature-based programming model
Through the examples of 4.1 and 4.2, we can find that both types of Messagesender and processor are implementations of composablepartdefintion, and in both of these types, we pass export and import (ImportMany) attribute to define the features that are exposed and the functions that are referenced. Compositioncontainer searches all composable component definitions through the component catalog of the assembly where the two classes are located, and then creates the export object with these definitions when the composition is executed, implementing a combination of components according to the constraint contract of the import declaration.
In this programming model, it allows us to:
(1) Using the traditional OOP type definition to define a composablepartdefinition, there is no doubt that this basically does not introduce the complex concept;
(2) using meta-data such as Export/import/importmany to declare the composition function is very simple and easy to understand.
Compositioncontainer will build this part-corresponding composablepartdefinition and other composablepartdefinition of the component directory in the background, when performing the combination, Create instance execution combinations with definition.
5 , MEF vs MAF vs Unity
When learning MEF, you often ask the question of what the difference is between a plug-in framework like MEF and MAF and an IOC framework like unity. The biggest difference between MEF and MAF (Managed Addin Framework) is that the former focuses on using a very simple way to support scalable support with strong flexibility, which focuses on plug-in platform architectures with physical isolation, security, and multi-versioning support; The difference between MEF and unity is that the former emphasizes the combination and the latter emphasizes dependency injection.
6 , MEF Summary
MEF has 3 points to make me very deep, first of all, the design of composite primitives, followed by the feature-based programming model, and finally the implementation of the MEF method.
Composite primitives are the essence of extensible support, and they look very simple, but have the ability to support powerful functionality without sacrificing flexibility. "Boulevard to Jane", however, the degree of "Jane" is really different from each other, the MEF "Jane" really makes people admire pleasantly surprised. This framework is also a frame that I like very much in addition to ObjectBuilder, and it's really nice to see the code. The work of heaven and man! The creative power of these people is so powerful!
The feature-based programming model, which allows us to define a component with a combination of capabilities using the "class definition + attribute declaration", makes it very, very simple to write components based on MEF! This also makes me feel the charm of the context-oriented programming approach again. Later I will also introduce a context-based design of FW that I have done, and the idea of MEF is somewhat similar.
When the MEF is implemented, its top-level namespace is System.ComponentModel.Composition, which divides Attributemodel, diagnostics, Hosting, Primitives, The Reflectionmodel namespace. The MEF's top-level namespace defines the features we use the most, and the bottom namespaces are used to define attribute models, diagnostic support, MEF hosts, composite primitives, and reflection models, and the overall implementation is very clear and concise! Look, I fell in love with this thing at first sight!
7 , another example of an attribute-based programming model
I originally designed a feature-based intelligent body programming framework. First, let me briefly describe what a smart body is. Intelligence is the software agent, using software to simulate human characteristics, including intelligence, initiative, sociality, perception and so on. From an implementation perspective, an agent is a thread-bound, message-queuing object that uses threads to simulate the human brain and use message queues to simulate brain memory. When the agent receives a message, its thread takes over to handle it. According to the above description, you must think that using OOP to develop a smart body is a bit cumbersome. OK, let's see how I use context to implement the agent.
7.1 use attributes to declare a "person" with perceived ability and initiative
here is the code snippet:
[Agent] Public class Someperson { [Intelligent] publicvirtual openthedoor () { // Open Door, initiative method } [Sensible (environment.temperature)] publicvirtual Ontemperaturechanged (Sensibilitycontext context) { // When sensing a response to a temperature change, a perceptual statement } }
7.2 Create a smart body
Here is the code snippet:
var New Agentcontainer (); var // build a real smart body in the background //
Agentframework has a similar design approach to MEF (of course, our internal strength and Microsoft are not comparable), through the "definition of type + declaration of smart body Characteristics" to define the agent, this way is simple, flexible and extensible!
. The subtle design that is worth experiencing in net