Hlavní menu
Nástroje |
UvodDoKomponent.MEFExample HistoryHide minor edits - Show changes to output 28 January 2015, 15:05
by
- Added lines 14-15:
-> %width=500px%Attach:mef.png 28 January 2015, 13:47
by
- Changed lines 1-2 from:
Original site of this example [[more -> http://www.codeproject.com/Articles/188054/An-Introduction-to-Managed-Extensibility-Framework]]. to:
Original site of this [[example -> http://www.codeproject.com/Articles/188054/An-Introduction-to-Managed-Extensibility-Framework]]. 28 January 2015, 13:47
by
- Changed line 362 from:
So in this first part of the MEF series, we learnt about the basics of MEF, its applicability, importance of *Export*, *Import*, *ImportMany* attributes, *Assembly* and *Directory catalogs*, *dynamic component discovery*, etc. But there is a lot more stuff to learn about MEF. to:
So in this first part of the MEF series, we learnt about the basics of MEF, its applicability, importance of *Export*, *Import*, *[=ImportMany=]* attributes, *Assembly* and *Directory catalogs*, *dynamic component discovery*, etc. But there is a lot more stuff to learn about MEF ;) 28 January 2015, 13:36
by
- Changed lines 155-156 from:
Well by this time, we have learnt something about MEF, how it works and also we have successfully added one component in our application. Now let us enhance our application so that it can handle all the other components like Subtraction, Multiplication and Division. to:
Well by this time, we have learnt something about MEF, how it works and also we have successfully added one component in our application. Now let us enhance our application so that it can handle all the other components like *Subtraction*, *Multiplication* and *Division*. 28 January 2015, 13:32
by
- Added lines 43-46:
First of all, we need to add reference to *[=System.ComponentModel.Composition=]* assembly into the project. Also a reference of the ''[=CalculatorContract.dll=]'' is added. Deleted lines 67-70:
First of all, we need to add reference to *[=System.ComponentModel.Composition=]* assembly into the project. Also a reference of the ''[=CalculatorContract.dll=]'' is added. 28 January 2015, 13:29
by
- Changed lines 15-16 from:
Let us create a simple calculator for the demonstration. Our sample application will have four basic arithmetic operations, viz. Add, Subtract, Multiply and Division. With that in mind, let us create our project structure as under: to:
Let us create a simple calculator for the demonstration. Our sample application will have four basic arithmetic operations, viz. *Add*, *Subtract*, *Multiply* and *Division*. With that in mind, let us create our project structure as under: 28 January 2015, 13:28
by
- Changed lines 4-5 from:
Let's repeat terminologie again :) to:
Let's repeat terminology again :) 28 January 2015, 13:27
by
- Added lines 1-2:
Original site of this example [[more -> http://www.codeproject.com/Articles/188054/An-Introduction-to-Managed-Extensibility-Framework]]. Added lines 17-18:
%width=300px%Attach:mefexample1.jpg Added lines 152-153:
%width=400px%Attach:mefexample3.jpg Added lines 159-160:
%width=300px%Attach:mefexample4.jpg Changed lines 259-260 from:
5.jpg to:
%width=900px%Attach:mefexample5.jpg Changed lines 263-264 from:
Correspondingly, the ''GetResult'' function has been changed a little bit. It now accepts a third parameter which specifies the operation type and based on that, the Exported parts will be invoked. to:
Correspondingly, the ''[=GetResult=]'' function has been changed a little bit. It now accepts a third parameter which specifies the operation type and based on that, the Exported parts will be invoked. Changed lines 276-277 from:
6.jpg to:
%width=400px%Attach:mefexample6.jpg Changed lines 287-288 from:
7.jpg to:
%width=300px%Attach:mefexample7.jpg Changed lines 291-292 from:
We have added only two DLLs there, viz., Add and Subtraction and removed the ''Add.cs'' and ''Subtract.cs'' files from *[=CompositionHelper project=]*. to:
We have added only two [=DLLs=] there, viz., Add and Subtraction and removed the ''Add.cs'' and ''Subtract.cs'' files from *[=CompositionHelper project=]*. Changed lines 340-345 from:
8.jpg And the *AssemblyCatalog has two parts (Divide and Multiply)*: 9.jpg to:
%width=900px%Attach:mefexample8.jpg And the *[=AssemblyCatalog=] has two parts (Divide and Multiply)*: %width=900px%Attach:mefexample9.jpg Changed lines 350-351 from:
10.jpg to:
%width=400px%Attach:mefexample10.jpg Changed lines 355-360 from:
MEF breaks the tightly coupled dependencies across the application but respects the type checking of the loosely coupled parts. Applications can be extended. Components can be added at runtime. Dynamic discovery of the components. Great piece of reusability. to:
*MEF breaks the tightly coupled dependencies across the application but respects the type checking of the loosely coupled parts. *Applications can be extended. *Components can be added at runtime. *Dynamic discovery of the components. *Great piece of reusability. Changed lines 362-367 from:
So in this first part of the MEF series, we learnt about the basics of MEF, its applicability, importance of Export, Import, ImportMany attributes, Assembly and Directory catalogs, dynamic component discovery, etc. But there is a lot more stuff to learn about MEF. In the next part or subsequent parts, we will look into some attributes, catalogs, more practical examples with different kind of applications using MEF. Thanks for reading. Longer version of this example [[more -> http://www.codeproject.com/Articles/188054/An-Introduction-to-Managed-Extensibility-Framework]]. to:
So in this first part of the MEF series, we learnt about the basics of MEF, its applicability, importance of *Export*, *Import*, *ImportMany* attributes, *Assembly* and *Directory catalogs*, *dynamic component discovery*, etc. But there is a lot more stuff to learn about MEF. 28 January 2015, 13:09
by
- Changed lines 1-61 from:
h2. Evil Wizard Example This is a very simple example, nevertheless eligible to understand the basis of MEF. %width=150px%Attach:Evil-wizard.png h3. Step 1. Add MEF to our Visual Studio solution Adding MEF to your VS solution could not be easier. MEF is part of the .NET 4 Framework, so you can just Add a Reference as you would do with any .NET assembly: Into class *[=EvilWizard=]* add a reference to *[=System.ComponentModel.Composition=]* h3. Step 2. Define the [=EvilWizard=] as an Import Part The next step is to tell MEF that our *[=EvilWizard=]* class is a ''part''. Furthermore, it is an ''import'' that is going to consume a series of services, that is, is going to use a ''''Hat service'''', a ''''Robe service'''' and a collection of ''''[=ISpell services=]''''. In order to do this, we will use MEF attribute based programming model, and we will decorate the *[=EvilWizard=]* components with the *[Import]* and * [=[ImportMany]=]* attributes as shown below: %width=600px%Attach:theevilwizard.png If you have not guessed it yet, we use the *[Import]* attribute to represent a single service and *[=[ImportMany]=]* to represent a multiplicity of services. These attributes also represent ''default contracts'', but we will deal with contracts in upcoming articles so do not worry for now. h3. Step 3. Define the Hat, Robe and Spells as Export Parts We continue by defining the Hat, Robe and Spells as parts that provide services: %width=600px%Attach:wizardarsenal.PNG Notice how we used the *[Export]* attribute to decorate a class that provides a service and the *[=[InheritedExport]=]* attribute to decorate an interface and ensure that ''anything that implements that interface'' becomes a part. h3. Step 4. Discover The Parts and Setup The Container Now that we have all the parts of our system ready, the next step consists in instantiating a catalog that will discover all parts within our assembly: %width=600px%Attach:setcatalog.PNG And passing this catalog to our MEF container so it will know which parts are available in our system: %width=600px%Attach:setcontainer.PNG h3. Step 5. Let the magic happen Finally, composing our evil wizard with other parts (hat, robe and spells) is as easy as: %width=600px%Attach:tadaaaa.PNG And there we have our evil wizard kicking ass: %width=600px%Attach:tadaresult.png h3. Step 6. Extending our RPG Extending our RPG at this moment (for instance, adding new spells) would be as easy as adding new parts in a new assembly. We can use a *[=[DirectoryCatalog ]=]* instead of a *[=[AssemblyCatalog ]=]* to point to a path where we can drop all these new assemblies packed with new spells of destruction and mayhem. Author of this example [[(original site)-> http://www.barbarianmeetscoding.com/blog/2012/08/14/barbarian-meets-mef-managed-extensiblity-framework/]] [[Jaime González García-> http://www.barbarianmeetscoding.com/about/]]. As a final note, you can find the code sample at [[GitHub-> https://github.com/Vintharas/Barbarian-Meets-MEF]]. to:
h2. MEF Related Terminologies Let's repeat terminologie again :) * *Part*: A Part is an object (e.g. a class, a method or a property) that can be imported or exported to the application. * *Catalog*: An object that helps in discovering the available composable parts from an assembly or a directory. * *Contract*: The import and exported parts need to talk between themselves via some contract (e.g. an Interface or predefined data type like string) * *Import Attribute*: It defines the need that a part has. It is applicable only for single Export Attribute. * *ImportMany Attribute* : It is similar to Import Attribute but supports for multiple Export Attributes. * *Export Attribute* : The import attribute creates the needs. The Export attribute fulfills that. It exposes those parts that will participate in the composition. * *Compose*: In MEF jargon, Compose is that area where the Exported parts will be assembled with the imported ones. h2. A Simple Working Example with Only a Single Export Part in Current Assembly Let us create a simple calculator for the demonstration. Our sample application will have four basic arithmetic operations, viz. Add, Subtract, Multiply and Division. With that in mind, let us create our project structure as under: The solution file *[=CalculatorDemoUsingMEF=]* has three projects: * ''[=CalculatorContract=]'' * ''[=CalculatorUI=]'' * ''[=CompositionHelper=]'' h3. a) Description of [@CalculatorContract@] Project Here, we basically define the contract or interface that the concrete components of Calculator say ''Add'', ''Subtract'', etc. must implement. The *[=ICalculator=]* interface is very simple as described below: [@ namespace CalculatorContract { public interface ICalculator { int GetNumber(int num1, int num2); } } @] h3. b) Description of [@CompositionHelper@] Project In this project, we will create the various components needed for the Calculator like Addition, subtraction, etc. The ''Add.cs'' file is the component used for Addition operation. Let us look into the ''Add.cs'' file: [@ using System.ComponentModel.Composition; using CalculatorContract; namespace CompositionHelper { [Export(typeof(ICalculator))] public class Add:ICalculator { #region Interface members public int GetNumber(int num1, int num2) { return num1 + num2; } #endregion } } @] First of all, we need to add reference to *[=System.ComponentModel.Composition=]* assembly into the project. Also a reference of the ''[=CalculatorContract.dll=]'' is added. The class is decorated by the *Export* attribute which indicates that this class will be exported to the composition model and it respects only of the ''[=ICalculator=]'' contract/ interface type. The ''[=CalcliComposition.cs=]'' file is the part where the Composition happens. [@ using System; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Reflection; using CalculatorContract; namespace CompositionHelper { public class CalciCompositionHelper { [Import(typeof(ICalculator))] public ICalculator CalciPlugin { get; set; } /// <summary> /// Assembles the calculator components /// </summary> public void AssembleCalculatorComponents() { try { //Step 1: Initializes a new instance of the // System.ComponentModel.Composition.Hosting.AssemblyCatalog // class with the current executing assembly. var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); //Step 2: The assemblies obtained in step 1 are added to the //CompositionContainer var container = new CompositionContainer(catalog); //Step 3: Composable parts are created here i.e. //the Import and Export components // assembles here container.ComposeParts(this); } catch (Exception ex) { throw ex; } } /// <summary> /// Sends the result back to the client /// </summary> /// <param name="num1"></param> /// <param name="num2"></param> /// <returns></returns> public int GetResult(int num1, int num2) { return CalciPlugin.GetNumber(num1, num2); } } } @] The *[=AssembleCalculatorComponent=]* function needs some attention. In this function, we are first looking for the catalogs from where the parts are coming. Once identified, the catalogs are held in a container and lastly the parts are composed. h3. c) Description of [@CalculatorUI@] Project In this project, the UI is displayed. It adds a reference to the ''[=CalculatorComponentComposition.dll=]'' . Let us look into the Add button click event code: [@ objCompHelper = new CalciCompositionHelper(); //Assembles the calculator components that will participate in composition objCompHelper.AssembleCalculatorComponents(); //Gets the result var result = objCompHelper.GetResult(Convert.ToInt32(txtFirstNumber.Text), Convert.ToInt32(txtSecondNumber.Text)); //Display the result txtResult.Text = result.ToString(); @] First, we are assembling the calculator components that will participate in the composition. Then calling the Addition component for the needed operation. The final output is as shown below: h2. A Simple Working Example with Multiple Export Part in Current Assembly Well by this time, we have learnt something about MEF, how it works and also we have successfully added one component in our application. Now let us enhance our application so that it can handle all the other components like Subtraction, Multiplication and Division. So let us add the various component parts in the application. The project structure will now become: As can be figured out, there is not much change expected, we have added three new parts which are highlighted. Let us now visit the ''Add.cs'' file again: [@ using System.ComponentModel.Composition; using CalculatorContract; namespace CompositionHelper { [Export(typeof(ICalculator))] [ExportMetadata("CalciMetaData", "Add")] public class Add:ICalculator { #region Interface members public int GetNumber(int num1, int num2) { return num1 + num2; } #endregion } } @] We have found that there is a new attribute call *[=ExportMetadata=]*. This new attribute will help us to determine at runtime which implementation to use. It is a form of name value pair. The first parameter of this attribute is the name of the metadata. It's type is *string*. The next one which is an object holds the value of the metadata. It is by which we will decide which operation will be called. A similar implementation has been followed for the rest of the Exportable parts. Next, let us have a look at the ''[=CalciCompositionHelper.cs=]'' file: [@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Reflection; using CalculatorContract; namespace CompositionHelper { public class CalciCompositionHelper { [ImportMany] public System.Lazy<ICalculator, IDictionary<string, object>>[] CalciPlugins { get; set; } /// <summary> /// Assembles the calculator components /// </summary> public void AssembleCalculatorComponents() { try { //Step 1: Initializes a new instance of the // System.ComponentModel.Composition.Hosting.AssemblyCatalog // class with the current executing assembly. var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); //Step 2: The assemblies obtained in step 1 are added to the //CompositionContainer var container = new CompositionContainer(catalog); //Step 3: Composable parts are created here i.e. //the Import and Export components // assemble here container.ComposeParts(this); } catch (Exception ex) { throw ex; } } /// <summary> /// Sends the result back to the client /// </summary> /// <param name="num1"></param> /// <param name="num2"></param> /// <returns></returns> public int GetResult(int num1, int num2, string operationType) { int result = 0; foreach (var CalciPlugin in CalciPlugins) { if ((string)CalciPlugin.Metadata["CalciMetaData"] == operationType) { result = CalciPlugin.Value.GetNumber(num1, num2); break; } } return result; } } } @] The first change that we observe is that now we have *[=ImportMany=]* attribute instead of *[=Import=]* attribute. The *[=Import=]* attribute is filled always by a single *[=Export=]* attribute while *[=ImportMany=]* attribute can be filled by any number of *[=Export=]* attribute. When we run the application, we can figure out the various parts that participate in composition. 5.jpg One more noticeable point is the *[=Lazy<T>=]* class basically defers the creation of large objects till the time we need that. In the sample code, the second parameter is the metadata that will be handled by MEF at runtime. Correspondingly, the ''GetResult'' function has been changed a little bit. It now accepts a third parameter which specifies the operation type and based on that, the Exported parts will be invoked. Finally, on the Concrete operations click event, we are passing the Operation types as: [@ private void btnAdd_Click(object sender, RoutedEventArgs e) { DoCalciOperation("Add"); } @] Once we run the application, the output will be as under (output shown only for multiplication operation): 6.jpg Hope this is equally helpful as the previous one. In the next part, we will explore some new catalog types and more features of MEF. h2. A Simple Working Example with Multiple Export Part using Aggregate Catalog and Directory Catalog Until now, we have seen that our Composable parts were residing in the current assembly. But what if they reside in different assemblies or in different location? Well, we have a solution for this too. We will see how Aggregate and Directory Catalog help us in such situations. Let us see the project structure now. 7.jpg We can figure out that one new project has been added to the solution file, i.e., Export Components. In that, we have a folder called Components where our export parts in the form of assemblies are stored (.dll files). We have added only two DLLs there, viz., Add and Subtraction and removed the ''Add.cs'' and ''Subtract.cs'' files from *[=CompositionHelper project=]*. Now let us visit the *[=AssembleCalculatorComponent=]* function again. [@ public void AssembleCalculatorComponents() { try { //Creating an instance of aggregate catalog. It aggregates other catalogs var aggregateCatalog = new AggregateCatalog(); //Build the directory path where the parts will be available var directoryPath = string.Concat(Path.GetDirectoryName (Assembly.GetExecutingAssembly().Location) .Split('\\').Reverse().Skip(3).Reverse().Aggregate ((a, b) => a + "\\" + b) , "\\", "ExportComponents\\Components"); //Load parts from the available DLLs in the specified path //using the directory catalog var directoryCatalog = new DirectoryCatalog(directoryPath, "*.dll"); //Load parts from the current assembly if available var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); //Add to the aggregate catalog aggregateCatalog.Catalogs.Add(directoryCatalog); aggregateCatalog.Catalogs.Add(asmCatalog); //Crete the composition container var container = new CompositionContainer(aggregateCatalog); // Composable parts are created here i.e. // the Import and Export components assembles here container.ComposeParts(this); } catch (Exception ex) { throw ex; } } @] As can be seen, initially we have created an *[=AggregateCatalog=]* that will aggregate other catalogs. Then we are picking up the Exportable Components from the Components directory. If we run the application, we can find that the *Directory Catalog has two parts (Add and Subtract)*. 8.jpg And the *AssemblyCatalog has two parts (Divide and Multiply)*: 9.jpg After the parts have been discovered, they are then added to the *[=AggragateCatalog=]* which is being added to the *[=CompositionContainer=]*. And finally, the parts gets composed. Running the application brings out the desired output (output shown only for Addition operation). 10.jpg h2. Advantages MEF has many advantages as we have seen by this time. However, some of the common advantages are listed below: MEF breaks the tightly coupled dependencies across the application but respects the type checking of the loosely coupled parts. Applications can be extended. Components can be added at runtime. Dynamic discovery of the components. Great piece of reusability. h2. Conclusion So in this first part of the MEF series, we learnt about the basics of MEF, its applicability, importance of Export, Import, ImportMany attributes, Assembly and Directory catalogs, dynamic component discovery, etc. But there is a lot more stuff to learn about MEF. In the next part or subsequent parts, we will look into some attributes, catalogs, more practical examples with different kind of applications using MEF. Thanks for reading. Changed lines 359-361 from:
Another "Hello World!" [[example-> http://www.codeproject.com/Articles/56635/Managed-Extensibility-Framework]] [[10 reasons why to use MEF -> http://csharperimage.jeremylikness.com/2010/04/ten-reasons-to-use-managed.html]] to:
28 January 2015, 11:21
by
- Changed lines 50-58 from:
Extending our RPG at this moment (for instance, adding new spells) would be as easy as adding new parts in a new assembly. We can use a DirectoryCatalog instead of a AssemblyCatalog to point to a path where we can drop all these new assemblies packed with new spells of destruction and mayhem. As a final note, you can find the code sample at GitHub. Original example site here. to:
Extending our RPG at this moment (for instance, adding new spells) would be as easy as adding new parts in a new assembly. We can use a *[=[DirectoryCatalog ]=]* instead of a *[=[AssemblyCatalog ]=]* to point to a path where we can drop all these new assemblies packed with new spells of destruction and mayhem. Author of this example [[(original site)-> http://www.barbarianmeetscoding.com/blog/2012/08/14/barbarian-meets-mef-managed-extensiblity-framework/]] [[Jaime González García-> http://www.barbarianmeetscoding.com/about/]]. As a final note, you can find the code sample at [[GitHub-> https://github.com/Vintharas/Barbarian-Meets-MEF]]. 28 January 2015, 11:14
by
- Changed lines 5-6 from:
Attach:Evil-wizard.png to:
%width=150px%Attach:Evil-wizard.png Changed lines 16-19 from:
If you have not guessed it yet, we use the *[Import]* attribute to represent a single service and *[=[ImportMany]=]* to represent a multiplicity of services. These attributes also represent default contracts, but we will deal with contracts in upcoming articles so do not worry for now. In order to do this, we will use MEF attribute based programming model, and we will decorate the *[=EvilWizard=]* components with the *[Import]* and *[=[ImportMany]=]* attributes as shown below: to:
%width=600px%Attach:theevilwizard.png If you have not guessed it yet, we use the *[Import]* attribute to represent a single service and *[=[ImportMany]=]* to represent a multiplicity of services. These attributes also represent ''default contracts'', but we will deal with contracts in upcoming articles so do not worry for now. Changed lines 24-25 from:
Notice how we used the [Export] attribute to decorate a class that provides a service and the [InheritedExport] attribute to decorate an interface and ensure that anything that implements that interface becomes a part. to:
%width=600px%Attach:wizardarsenal.PNG Notice how we used the *[Export]* attribute to decorate a class that provides a service and the *[=[InheritedExport]=]* attribute to decorate an interface and ensure that ''anything that implements that interface'' becomes a part. Added lines 32-33:
%width=600px%Attach:setcatalog.PNG Added lines 36-37:
%width=600px%Attach:setcontainer.PNG Added lines 42-43:
%width=600px%Attach:tadaaaa.PNG Added lines 46-47:
%width=600px%Attach:tadaresult.png 28 January 2015, 10:54
by
- Added lines 2-6:
This is a very simple example, nevertheless eligible to understand the basis of MEF. Attach:Evil-wizard.png Changed lines 16-19 from:
If you have not guessed it yet, we use the *[Import]* attribute to represent a single service and * [=[ImportMany]=]* to represent a multiplicity of services. These attributes also represent default contracts, but we will deal with contracts in upcoming articles so do not worry for now. In order to do this, we will use MEF attribute based programming model, and we will decorate the EvilWizard components with the [Import] and [ImportMany] attributes as shown below: to:
If you have not guessed it yet, we use the *[Import]* attribute to represent a single service and *[=[ImportMany]=]* to represent a multiplicity of services. These attributes also represent default contracts, but we will deal with contracts in upcoming articles so do not worry for now. In order to do this, we will use MEF attribute based programming model, and we will decorate the *[=EvilWizard=]* components with the *[Import]* and *[=[ImportMany]=]* attributes as shown below: 28 January 2015, 10:47
by
- Added lines 1-43:
h2. Evil Wizard Example h3. Step 1. Add MEF to our Visual Studio solution Adding MEF to your VS solution could not be easier. MEF is part of the .NET 4 Framework, so you can just Add a Reference as you would do with any .NET assembly: Into class *[=EvilWizard=]* add a reference to *[=System.ComponentModel.Composition=]* h3. Step 2. Define the [=EvilWizard=] as an Import Part The next step is to tell MEF that our *[=EvilWizard=]* class is a ''part''. Furthermore, it is an ''import'' that is going to consume a series of services, that is, is going to use a ''''Hat service'''', a ''''Robe service'''' and a collection of ''''[=ISpell services=]''''. In order to do this, we will use MEF attribute based programming model, and we will decorate the *[=EvilWizard=]* components with the *[Import]* and * [=[ImportMany]=]* attributes as shown below: If you have not guessed it yet, we use the *[Import]* attribute to represent a single service and * [=[ImportMany]=]* to represent a multiplicity of services. These attributes also represent default contracts, but we will deal with contracts in upcoming articles so do not worry for now. In order to do this, we will use MEF attribute based programming model, and we will decorate the EvilWizard components with the [Import] and [ImportMany] attributes as shown below: h3. Step 3. Define the Hat, Robe and Spells as Export Parts We continue by defining the Hat, Robe and Spells as parts that provide services: Notice how we used the [Export] attribute to decorate a class that provides a service and the [InheritedExport] attribute to decorate an interface and ensure that anything that implements that interface becomes a part. h3. Step 4. Discover The Parts and Setup The Container Now that we have all the parts of our system ready, the next step consists in instantiating a catalog that will discover all parts within our assembly: And passing this catalog to our MEF container so it will know which parts are available in our system: h3. Step 5. Let the magic happen Finally, composing our evil wizard with other parts (hat, robe and spells) is as easy as: And there we have our evil wizard kicking ass: h3. Step 6. Extending our RPG Extending our RPG at this moment (for instance, adding new spells) would be as easy as adding new parts in a new assembly. We can use a DirectoryCatalog instead of a AssemblyCatalog to point to a path where we can drop all these new assemblies packed with new spells of destruction and mayhem. As a final note, you can find the code sample at GitHub. Original example site here. 04 January 2015, 22:06
by
- Added lines 1-5:
Longer version of this example [[more -> http://www.codeproject.com/Articles/188054/An-Introduction-to-Managed-Extensibility-Framework]]. Another "Hello World!" [[example-> http://www.codeproject.com/Articles/56635/Managed-Extensibility-Framework]] [[10 reasons why to use MEF -> http://csharperimage.jeremylikness.com/2010/04/ten-reasons-to-use-managed.html]] |