.NET Framework 4 has a lot of new features and it can be daunting to decide what to look at first. Fortunately or unfortunately (it has been a long trek from start to Beta 2) I have been working with Visual Studio 2010 and .NET 4 for the last 16 months. I will share with you my favorite features starting with Managed Extensibility Framework (MEF).
Fire up Visual Studio and join me as I walk through a simple example of MEF. If you have not downloaded VS2010 yet you can get it from the Visual Studio 2010 and .NET Framework 4 Beta 2 page.
Visual Studio 2010 Start Page
From the Start Page click New Project and launch the New Project Window. The Window will be similar to below depending on your language. Make sure you have .NET Framework 4 selected. Then Select Windows Form Application, name the project HelloMEF, select the location and click OK.
The next step is to modify the basic Form class that is created by the template.
- Open the Solution Explorer and rename Forrm1.cs to FormMEF.cs
- Click yes to rename the Form1 class to FormMEF
- Open the Form design if it is not for FormMEF
- Click on the Form and change the text from Form1 to Hello MEF
- Drop a MenuStrip on the Form
- Change the name to menuStrip
- Add the following menu items
- Double click on E&xit and put this.Close(); in the method handler.
- Now copy the method handler and name it templateToolStripMenuItem_Click
- Then type the follow code
private void templateToolStripMenuItem_Click(object sender, EventArgs e) { ToolStripMenuItem tempMenuItem = sender as ToolStripMenuItem; ((IAddin)tempMenuItem.Tag).Show();
- Right Click on the IAddin type and select Generate|New Type...
Here is a cool new feature. I use to have to stop and go manually insert the new type. It would stop the flow of my coding. Now I just go write code. Then go back and generate the missing stub code! - Once you have the IAddin interface created the Show will get a squiggle line. Right click and have it add the method to the interface.
- Add a reference to System.ComponentModel.Composition. This is the key MEF assembly to use. MEF works on the notion of an object container with support for a catalog. When you want a type from MEF you make a request of the container for the type or name requested. In the next step, we will create the catalog and container.
- Add a using statement for System.ComponentModel.Composition.
- MEF works by telling a catalog what is available (Export types) and types using the contents of the catalog (Import). In this case we want to dynamically add “Addins”. A property will be created that MEF can load up with IAddins.
[ImportMany] public IAddin[] Addins { get; set; }
This tells MEF that it should find IAddins and return all of the objects that satisfy this condition in an array of IAddin. - Jump back to the Form and double click on the Form to generate the Form Load event. In this event will be the wiring of IAddins into the menu.
private void FormMEF_Load(object sender, EventArgs e) { ToolStripMenuItem menuItem; foreach (IAddin addin in Addins) { menuItem = new ToolStripMenuItem(addin.Name); menuItem.Tag = addin; menuItem.Click += new EventHandler(templateToolStripMenuItem_Click); addinToolStripMenuItem.DropDownItems.Add(menuItem); } }
- Use Generate Property to add Name to IAddin. You will need to change the type to string as it will potentially use Image since the construct can take an Image or a String.
- Click on the Program.cs file.
- First add the following using statements (note this will not work if you do not have both using statements)
-
- System.ComponentModel.Composition
- System.ComponentModel.Composition.Hosting
- As I said earlier MEF requires a catalog and a container. To create a catalog to find types and contracts
AggregateCatalog catalog = new AggregateCatalog(); catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath));
In this case I am creating a catalog that contains exported types from my executing assembly and any assembly that is in the application startup path. - The next step is to create the container
var container = new CompositionContainer(catalog);
- This next part is create the form and have the container fulfill its imports
Form frm = new FormMEF();
- Finally change the Run parameter and run the program. You should at this point get a form with no Addin menu items.
Application.Run(frm);
- Now to create an Addin.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.ComponentModel.Composition; namespace HelloMEF { [Export(typeof(IAddin))] public class FirstAddin : IAddin { public void Show() { MessageBox.Show("Hello from 1st Addin"); } public string Name { get { return "First Addin"; } } } }
- Run the application again.
Create another assembly with an IAddin and have it compile into the same directory as HelloMEF. When you run the application you now get to Addin menu items.
If you want to be even more scary here is the instructions to have MEF find the Form and dynamically use a different Form at run time.
- Export the form using
[Export("FormMEF", typeof(Form))]
- Modify the Program Main method
[STAThread] static void Main(string[] parameters) { string loadForm = "FormMEF"; if (parameters.Count() > 0) { loadForm = parameters[0]; } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // Setup MEF AggregateCatalog catalog = new AggregateCatalog(); catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath)); var container = new CompositionContainer(catalog); // Get FormMEF and satisfy its imports var frm = container.GetExportedValue
- Move your addin class and Forrm into its own class library.
- You can create another form with a different contract name. Then pass it into the program. Voila.
By the way there is a Compact Framework version. You can find it on CodePlex.
Comments