imageWorkshop: Specifying a Contract

The previous workshop demonstrated how you could make use of a “part” without the need to “new it up.” However, it provided no benefit over simply “newing it up.” You may as well have simply done this in the MainPage class's constructor, like this:

MyImportedPersonPart = new PersonPart();

The MainPage class is still tightly coupled to the PersonPart class. The benefits of MEF are realized only when you make use of a contract to decouple them, exporting the part according to an interface instead of its concrete implementation. By taking a contract-based approach, you can then swap in alternative parts to the PersonPart part, depending on the current scenario. This is particularly useful for improving the testability of your application, allowing you to import “mock” parts that help you to test a component in isolation from the rest of the application. It's also useful for creating a plug-in architecture, where plug-ins simply need to conform to a given interface in order for the application to be able to consume them, with MEF handling the discovering of the plug-ins.

A contract is just an interface that a part implements. A class tells MEF to import a part that implements that interface, and MEF will discover it and compose the two together. In this workshop, we'll refactor the code from the previous workshop and implement a contract to decouple the MainPage and PersonPart classes.

  1. The first step is to create the contract. This contract will simply be an interface that requires classes to implement a property named Name. Add a new file to your project named IPersonPart.cs, using the Code File item template. Add the following code to it:
    namespace Chapter14Sample
    {
        public interface IPersonPart
        {
            string Name { get;set; }
        }
    }

    images Note An easier way to create this file is to right-click somewhere in the code for the PersonPart class, and select Refactor images Extract Interface from the context menu. The dialog that appears will help create the interface for you.

  2. Now have the PersonPart class implement this interface.
    [Export]
    public class PersonPart : IPersonPart
  3. You now need to change the Export attribute to export the part by its interface rather than its concrete implementation. You do this by passing the interface's type to the Export attributes constructor, like so:
    [Export(typeof(IPersonPart))]
    public class PersonPart : IPersonPart
  4. Now change the MyImportedPersonPart property's type to IPersonPart, as follows:
    [Import]
    public IPersonPart MyImportedPersonPart { get; set; }

The MainPage class and PersonPart class are now decoupled, with the MainPage class now knowing nothing about the PersonPart class, except the interface that it implements. MEF handles the discovery of the concrete implementation of the IPersonPart interface, and injects it into the MainPage class. If you now run your application, it will work exactly the same way as it did before.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset