C# Corner

Using MEF in a Windows Store App

Eric Vogel covers how to use the Managed Extensibility Framework (MEF) to extend a Windows Store application.

The Managed Extensibility Framework (MEF), introduced in .NET Framework 4, is a library that allows an application to be extended through the use of MEF components. In a sense, it's a composition layer for an application. An MEF component defines what it's capable of doing (exports) and its dependencies (imports). MEF may be used by .NET Framework 4.5 Web and client applications as well as Windows Store apps. In this article, I'll cover how to use the MEF NuGet package for Windows Store apps.

To get started, install the Microsoft.Composition NuGet package, shown in Figure 1.


[Click on image for larger view.]
Figure 1. NuGet installation of MEF for Windows Store apps.

The MEF System.Composition references should now be added to your project, as shown in Figure 2.


[Click on image for larger view.]
Figure 2. MEF Project References added.

Now it’s time to put MEF to good use. The sample application will allow the user to validate an input field using a custom validator. Each validator will be loaded as an MEF part from a BusinessRules assembly.

Next, let's add the supporting classes and interfaces that will be loaded via MEF. First, create a C# Windows Store apps Class Library named BusinessRules, and add it to the solution, as shown in Figure 3.


[Click on image for larger view.]
Figure 3. Adding the BusinessRules Class Library Project.

Next, add a NuGet project reference to MEF to the BusinessRules project. Now add an IValidate interface to the BusinessRules project. The IValidate interface will serve as the MEF contract for the custom validators. The IValidate interface defines a single Validate method that validates a given input string and returns a success or failure message.

namespace BusinessRules
{
    public interface IValidate
    {
        string Validate(string input);
    }
}

Now let's add the ValidateMetaData class, which is used to tag a specific concrete validator class for use by MEF. The ValidateMetaData class contains a single property named Name and overrides the ToString method for easy display in a client application.

namespace BusinessRules
{
    public class ValidateMetaData
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}

Now let’s add the email validator that will implement the IValidate interface. First, add using statements for the System.Composition and System.Text.RegularExpressions namespaces.

using System.Composition;
using System.Text.RegularExpressions;

Next, add an Export attribute passing in the IValidate Type to tell MEF that the class exports the IValidate interface.

[Export(typeof(IValidate))]

Then add an ExportMetadata attribute passing in "Name", "Email" to tell MEF the ValidateMetaData metadata property settings.

[ExportMetadata("Name", "Email")]

Now let's implement the IValidate interface’s Validate method to see if the input string matches an email pattern regular expression, and returns an appropriate success or failure message. The ValidateEmail class is shown in Listing 1.

Next, let's implement the ValidateUSPhone validator that checks if the input is a valid U.S. phone number. The class is very similar to the ValidateEmail class except that the metadata Name attribute is set to "U.S. Phone", and a phone regular expression is used to validate the input. The resulting code is shown in Listing 2.

Now it’s time to implement the client application that will load the input validators. The user will be able to enter a text input, select a validator, and then perform the validation through a button click. First, add a project reference to the BusinessRules project to the Windows Store project. Next, add the UI for the application. Open the MainPage.xaml and use the Grid element markup shown in Listing 3.

Now it’s time to put everything together and use MEF to load the business rule validators. Open up the MainPage.xaml.cs file. Then add using statements for the System.Composition, System.Composition.Hosting, and System.Reflection namespaces to the MainPage class as follows:

using System.Composition;
using System.Composition.Hosting;
using System.Reflection;

Then add a property named Validators to store a collection of validators that will be loaded through MEF using the ImportMany attribute.

[ImportMany]
public IEnumerable<Lazy<BusinessRules.IValidate, BusinessRules.ValidateMetaData>>
Validators { get; private set; }

Then add a member IValidate type variable to store the currently selected validator.

private BusinessRules.IValidate _selectedValidator;

Now it’s time to update the MainPage class constructor to initialize MEF. The first step is to setup the MEF configuration to load the BusinessRules assembly.

var configuration = new ContainerConfiguration()
                        .WithAssembly(typeof(BusinessRules.IValidate).GetTypeInfo().Assembly);

Then create the MEF CompositionHost through the ContainerConfiguration instance.

var compositionHost = configuration.CreateContainer();

Next, call the SatisfyImports method on the created CompositionHost object to have MEF set the Validators property from the BusinessRules assembly.

compositionHost.SatisfyImports(this);

The completed MainPage constructor should now look like the following code:

public MainPage()
 {
     this.InitializeComponent();

     var configuration = new ContainerConfiguration()
                 .WithAssembly(typeof(BusinessRules.IValidate).GetTypeInfo().Assembly);

     var compositionHost = configuration.CreateContainer();
     compositionHost.SatisfyImports(this);
 }

Now databind the ValidationTypes combobox from the Validators property in the OnNavigatedTo event handler as follows:

protected override void OnNavigatedTo(NavigationEventArgs e)
 {
     ValidationTypes.DataContext = Validators;
 }

Next, let's implement the Click event handler for the Validate button to call the selected validator and update the Result TextBlock. If there isn't a current selector, then "No validator was found," is displayed in the Result TextBlock.

private void Validate_Click(object sender, RoutedEventArgs e)
 {
     if (_selectedValidator == null)
         Result.Text = "No validator was found.";
     else
         Result.Text = _selectedValidator.Validate(Input.Text);
 }

The final step is to implement the SelectionChanged event handler for the ValidationTypes combobox. When the selected item changes, the _selectedValidator member field is set to the selected value.

private void ValidationTypes_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count > 0)
        _selectedValidator = ValidationTypes.SelectedValue as BusinessRules.IValidate;
}

The complete MainPage class implementation is shown in Listing 4. You should now be able to run the completed application, select either an Email or U.S. Phone validator and run the validator on the entered text, as shown in Figure 4.


[Click on image for larger view.]
Figure 4. Completed MEF demo.

MEF is a great library to have in your toolset when constructing a Windows Store app. You can use MEF to decouple your business needs from the UI layer, and increase the extensibility of your application. This is only one of the many use cases for MEF. Feel free to share how you’re using MEF to manage your application complexity in the comments section below.

About the Author

Eric Vogel is a Senior Software Developer for Red Cedar Solutions Group in Okemos, Michigan. He is the president of the Greater Lansing User Group for .NET. Eric enjoys learning about software architecture and craftsmanship, and is always looking for ways to create more robust and testable applications. Contact him at [email protected].

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events