code magazine - article_ understanding dependency injection and those pesky containers

Upload: bogdan-comsa

Post on 14-Apr-2018

231 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    1/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true

    Understanding DependencyInjection and Those PeskyContainers

    We seem to be an industry enamored with buzz words. Even though

    XmlHttpRequest has been around since the mid-90s, mainstream

    programmers didnt give it a second thought until someone attachedthe term AJAX to it. The same is true for the never-ending quest to

    put as many different words as we can in front of driven-

    development. Another term that hit the scene in recent years is

    dependency injection.

    Bringing form to concepts that had been around for a while,

    dependency injection (also known as DI) didnt kick into full force until

    Martin Fowler wrote his famous article in 2004. The development

    community grabbed onto the term and ran with it as the next big thing

    we should all be doing, which is great - except for the fact that DI

    seemed to be only a small part of what the community as a whole was

    doing.

    DI is an approach to providing one type with instances of the other

    types on which it may depend, all while keeping the types decoupled

    from one-another through the use of interfaces. Though defined in

    Wikipedia as an approach to testing computer programs, its more

    than just testing. That said, testing is an extremely good and

    important reason to use DI, because with it, you can write decoupled

    components, making it an integral part of good software testing. DI is

    a form of Inversion of Control and is sometimes confused as being the

    exact same thing. (Inversion of Control is a software principle whereas

    control of a class initialization and execution is delegated to another

    class, sometimes a container or a manager.) DI is a slight subset of

    Inversion of Control.

    Before digging into how implementat ions of DI work and how to use the

    DI Container, you need to understand the concept of coupled and

    decoupled software; the former being bad and the latter being thegood that becomes even better with DI.

    Software Coupling

    When writing software, its always a good idea to separate the

    concerns of the types involved. Separation of concerns means that

    each type has either only one, or a very small set of responsibilities. Of

    course, if you translate your software to the line of business for which

    its built, it immediately becomes apparent that a business process

    involves many steps and therefore many types.

    Most of the time, there is a need for one type to work hand-in-hand

    with another and perhaps become a sub-part of another. In other

    words, one class may depend on another. In fact, the parent type

    would very likely contain an instance of the type on which it depends,

    usually passed in through a constructor or a property.

    The problem is that this creates a coupling between the two types.

    Not only can the parent type not exist (or compile) without the

    dependent type, it can be stuck with the way that type wants to do

    things. Ill show you what I mean with an example of what not-to-do,

    and then Ill show you techniques for solving the problem.

    A Coupled Example

    Lets take a look at a great example of a business process that can be

    subdivided easily: e-commerce. Among other things, three of the

    functions that are involved in a check-out process are:

    By: Miguel Castro

    Miguel is an a rchitect withIDesign who specializes inarchitecture consulting andbuilding .NET solutions. Heis a Microsoft MVP andINETA speak er and hasbeen a software developerfor over 22 years. With aMicrosoft background thatgoes all the way back to VB1.0 (and QuickBasic in fact),Miguel jumped on .NET as

    soon as the first public Betawas released a nd hasprovided .NET solutions forclients around the country ina variety of industries. Heconsiders himself to be a.NET Develope r and Architectand has e qual love for bothVB and C#, and notolerance for langua gebigotry. Hes spoken atnumerous user groupsaround the country as wellas d eveloper conferences.

    Hes the a uthor of theCode Breeze code-generator,which among things can befound on his Web site:

    www.steelbluesolutions.com

    Miguel currently lives inLincoln Park, NJ with his wifeElena and his daughterVictoria.

    [email protected]

    DI in .NET 1.1

    Normally, I would

    consider this a dead

    product, but recently I

    had a team of South

    American developers

    approach me after a

    conference talk and

    mention that they have

    an old system written in

    http://www.steelbluesolutions.com/mailto:[email protected]://www.steelbluesolutions.com/
  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    2/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 2

    payment processing

    customer update

    notification

    After an order is placed, a customers credit card must be charged,

    after which the customer record needs to be updated with the order

    he/she placed and the product purchased. Lastly, the customer should

    receive an email with their receipt and order summary. An additional

    less critical process can be logging, which can take place at every

    step for internal auditing purposes.

    Lets start with a type that will contain the data involved in the

    example. This type is called OrderInfo and can be seen in Listing 1.

    To act upon this data, theres a type called Commerce with a method

    called ProcessOrder, which performs all the aforementioned sub-

    processes. In the interest of separating the concerns, I have created

    types called BillingProcessor, Customer, Notifier, and Logger.

    Each of them might be used from another class in another situation,

    but its also a good idea not to put everything in the Commerce type

    to encapsulate the check-out process.

    The four classes are shown in Listing 2. Notice that in the interest of

    simplicity, their methods have no real functionality. If they did, it

    would be complex and involve several resources, such as a database,the file system, or additional APIs like an email sender and a payment

    gateway. Also note that each of the methods of the four classes act

    upon different pieces of the OrderInfo type.

    The Commerce type incorporates each of the other four types by

    receiving an instance of each in its constructor. Think of this as an

    orchestrator or manager class. You can see this one in Listing 3.

    Assuming that you have an instance of OrderInfo with the necessary

    data, using the Commerce type can involve something like this:

    Commerce commerce = new Commerce(

    New BillingProcessor(),

    New Customer(),

    New Notifier(),New Logger());

    commerce.ProcessOrder(orderInfo);

    The problem here is two-fold. First, the Commerce type is completely

    and utterly coupled to the other four types. Not only can it not work

    without them, but its totally locked into the implementation that each

    provides. What if the system youre writing changes payment

    gateways in the future? If your application were written like the

    example snippet above, you would have to rewrite the entire

    BillingProcessor class, only to rewrite it again later. Of course you

    can have two different classes, but that would mean changing the

    code in the Commerce class in order to alter which new or different

    types gets received.

    The second problem is that the Commerce class is difficult to test.

    Eventually you will have to test the production functionality of the four

    classes that house the sub-processes, but what if you want to test

    the ProcessOrder method of the Commerce class to see how it

    handles the combination of the four processes without having to deal

    with the resource access that those processes might undertake?

    Writing a unit test for this method means having to bring in all four of

    the other types and whatever resource access was written into them.

    " coupled = bad "

    .NET 1.1. They still

    support and enhance

    this system but for

    corporate policy

    reasons, cannot

    upgrade it beyond 1.1.

    Interested in

    introducing DI to it,

    they asked me what

    their options are. To

    the best of my

    knowledge, none of the

    DI containers

    mentioned in this article

    support .NET 1.1

    because of their use of

    generics and/or lambda

    expressions. The make-

    shift container I wrote

    for this article can be

    easily modified to favor

    typeof statements

    over generics. Though

    nowhere as feature-rich

    as any of the other

    containers, it can

    certainly fulfill the basicDI requirements of .NET

    1.1 applications.

    DI and UnitTesting

    Although some may

    argue that DI is allabout unit testing, its

    actually about writing

    decoupled software.

    Thats what I wanted

    the focus of this article

    to be and thats why I

    didnt get deeply into

    the practice of unit

    testing or TDD. Using a

    DI container to assist

    you in developing

    components which

    depend on interfaces

    rather than classesallows you to test

    those components with

    test implementations of

    their dependencies,

    dependencies which

    can otherwise involve

    more complex

    resources, such as

    databases. Its not the

    DI container that

    assists you in testing;

    its the practices on

    which you are forced to

    focus when involvin a

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    3/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 3

    This is coupled behavior, and remember coupled = bad. But I didnt

    spend all that time writing code only to tell you not to do it this way.

    Im going to make adjustments to the code above in order to decouple

    my components and make everything more extensible and testable.

    A Decoupled Example

    The first step to decoupling application components is to abstract out

    the implementation from the definition in the four process classes. This

    way, you can provide a production implementation and test

    implementation later. So the first thing to do is refactor the definition

    of the classes out to four interfaces, as shown in Listing 4.

    Then youll modify the four process classes to implement their

    appropriate interface. In the interest of space, only the

    BillingProcessor class is included in this code snippet, but this same

    pattern applies to the other three process classes.

    Public class BillingProcessor : IBillingProcessor

    {

    Void IBillingProcessor.ProcessPayment(

    String customer,

    String creditCard,

    Double price)

    {

    // Perform billing gateway processing

    }}

    You can now write as many different billing processors as you want,

    each providing a different implementation of the interface. The key

    now is to modify the Commerce class so that it receives injections by

    way of the interfaces and not the concrete types as before. The

    rewrite of the Commerce class is in Listing 5.

    Ive provided the entire class again so you can see that the only thing

    that has changed is the type of the constructor arguments and the

    class fields. The method calls in the ProcessOrder method are exactly

    the same. The Commerce class makes these method calls and leaves

    their actual function to whatever the implementation classes are that

    were sent through the constructor. The Commerce typesdependencies were injected through the constructor without being

    coupled to the Commerce type. The only coupling that took place is

    through the interfaces and they act as plumbing. This is good coupling.

    This light coupling is DI in its simplest form. The components have

    been decoupled from one another and through the use of interfaces,

    the application can grow and change in the future and components

    can be swapped if and when necessary. In fact, in the context of

    Visual Studio projects, the Commerce class can sit in one assembly

    (possibly the main application), the process classes in another (or

    even four different ones), and both sides share a third assembly

    containing the interfaces.

    If you were to write a unit test against the Commerce class

    ProcessOrder method, you would no longer need the productioninstances of the four process classes, and certainly not even a

    reference to the assembly in which they live. You can write test

    versions that implement the interfaces in a totally different way,

    perhaps doing nothing at all except providing a dummy return value

    when one is expected. In fac t, ideally, you wouldnt need to write test

    implementations at all but can use a mocking framework to create

    them on-the- fly within the unit t est itself.

    The one thing that hasnt changed with this refactoring is the fact

    that whatever called the Commerce class still needs to instantiate

    the four process classes in order to inject them into the instance of

    Commerce. This is where a DI container will come in handy.

    DI container that does

    so. Testing is an

    important and involved

    topic and I felt it would

    digress from the core

    intent of this article.

    MEF 2

    I believe MEF to be a

    first-class c itizen in the

    world of DI and that

    belief is solidified

    further with MEF 2. In

    addition to providing

    better debugging

    capability for

    composition errors (a

    headache for many MEF

    users), MEF 2 adds

    some great registration

    features with a new

    RegistrationBuilder

    class.

    The c lass exposes an

    awesome fluent API

    that lets you export

    types using various

    techniques without the

    need to use attribute

    decorations. Among

    these are direct

    replacements for the

    existing attributes aswell as some very cool

    new techniques, such

    as exporting types that

    contain a certain

    property. MEF 2

    Preview is currently in

    its fifth iteration and

    can be obtained from

    http://mef.codeplex.com/releases/view/79090.

    You can also find a

    good Code-Project

    article at

    http://www.codeproject.c om/Articles/366583/ME

    2-Preview-Beginners-

    Guide thats worthchecking out.

    http://www.codeproject.com/Articles/366583/MEF-2-Preview-Beginners-Guidehttp://mef.codeplex.com/releases/view/79090
  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    4/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 4

    DI containers are about two things, R&R. No, not rest and relaxation.

    Im talking about registration and resolving. These are the acts of

    storing a list of types and later retrieving instances of them at will.

    " DI containers are about two things,R&R (registration and resolving) "

    The DI container is the tool that turns DI into architectural patterns

    that lets you satisfy a types dependencies easily and automatically. Itis a repository that typically associates interfaces with concrete

    types.

    How a DI Container Works

    DI containers all work in a very similar fashion. At the beginning of an

    applications execution-cycle, you need to register associations of

    concrete types to the interfaces that they implement. What makes

    containers different from one another is the way registration

    functionality is exposed. Later, when an instance of an interface

    implementation is requested, the container can offer an instance of

    the appropriate concrete type, called resolving. What makes the

    process of the instance assignment special is that it happens

    recursively, as many times as necessary.

    At the start of an app, you might register 20 types with 20 interfaces.

    When you request a type from the container by specifying an

    interface, not only do you get an instance of the associated type, but

    the container offers a bit more. The container looks at either the

    constructor arguments or the public properties and determines whether

    they are interface types. If they are interface types, it attempts to

    resolve them as well and set the argument or property value to the

    instance it resolved. The container then repeats the process for each

    of the resolved types as well. By the time it returns the type you

    requested, it has all its dependencies with it, and their dependencies,

    and so on down the line.

    Because essentially all containers work this way, theres no better way

    to fully understand what goes on behind the scene than to see thecode of a very simple DI container. Any container you use later, no

    matter how complex it may seem, is essentially a variation of what Ill

    show you here.

    Because you need to store associations of interfaces to concrete

    types, start by writing a simple class to represent this association:

    Public class ContainerItem

    {

    Public Type AbstractionType { get; set; }

    Public Type ConcreteType { get; set; }

    }

    Now its a matter of writing a class that will serve as the container and

    expose an API for adding instances ofContainerItem types. Listing 6

    shows the container class.

    As you can see, all the code does is expose a method called Register,

    which will let you store an association of an interface to a concrete

    type. Each association is stored in the container list, _Registrations.

    Now you just need to expose another method that will let you ask for

    whatever type is associated to a given interface. Call this method

    CreateType.

    Public T CreateType() where T : class

    {

    Object instance = null;

    Type type = typeof(T);

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    5/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 5

    ContainerItem containerItem =

    _Registrations.Where(item =>

    item.AbstractionType.

    Equals(type)).FirstOrDefault();

    If (containerItem != null)

    Instance = Activator.CreateInstance(

    ContainerItem.ConcreteType);

    Return instance;

    }

    This simple version of the CreateType method looks for an item in the

    registration list where the AbstractionType property is equal to the

    type requested in the generic argument. If it finds an entry, it takes

    the ConcreteType property and creates an instance of it to return.

    Where a DI container provides its real value is in the recursive walk it

    takes through the properties and/or constructor arguments of the

    types it resolves, in order to further resolve its dependencies. Modify

    the CreateType method to do just that.

    You also need to return an instance of the requested type if it isnt an

    interface. This way, the CreateType method can be used to

    instantiate a type that might not have been registered earlier, but still

    walk through it to resolve its dependencies. Listing 7 shows themodified CreateType method.

    It doesnt take a lot of code to take the type that is found in the list,

    go through the arguments of its constructor and if they are of an

    interface type, attempt to resolve them. You continue to do the same

    for those types, and so on until the type initially requested is returned.

    In order to use this simple container, modify the e-commerce code

    snippet I wrote back in the A Coupled Example section. The

    Commerce class will remain exactly the same, as will the interfaces

    and the four processes. Only the client must change.

    Container container = new Container();

    container.Register();

    container.Register();

    container.Register();

    container.Register();

    OrderInfo orderInfo = new OrderInfo()

    {

    CustomerName = "Miguel Castro",

    Email = "[email protected]",

    Product = "Laptop",

    Price = 1200,

    CreditCard = "1234567890"

    };

    Commerce commerce = container.CreateType();

    commerce.ProcessOrder(orderInfo);

    Keep in mind that in a real application, the registrations occur at

    startup and container is saved in a way that it can be accessed from

    anywhere. If any of the registered types were to also have interface-

    based constructor arguments, they would be resolved also, provided

    those interfaces were registered in the container.

    Any container you decide to use works in a very similar fashion to

    what Ive just demonstrated. There are many DI containers for you to

    choose from, according to your needs.

    mailto://[email protected]
  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    6/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 6

    u c our oug ome opu ar on a ners

    Although this article is not a tutorial on all the available DI containers

    out there, its worth talking briefly about a few of them and showing

    some simple examples.

    Unity is Microsofts answer to the call for DI containers. It works in a

    very similar fashion to the make-shift container you looked at in this

    article. In fact, the only difference youll note is the name of the

    container type and the names of the methods used to register and

    resolve. Heres the same container-usage example I used earlier, but

    using Microsoft Unity instead:

    UnityContainer container = new UnityContainer();

    container.RegisterType();

    container.RegisterType();

    container.RegisterType();

    container.RegisterType();

    OrderInfo orderInfo = new OrderInfo()

    {

    CustomerName = "Miguel Castro",

    Email = "[email protected]",

    Product = "Laptop",

    Price = 1200,CreditCard = "1234567890"

    };

    Commerce commerce =

    container.Resolve();

    commerce.ProcessOrder(orderInfo);

    Other popular containers include Castle Windsor, MEF, NInject,

    StructureMap, and Spring.NET. Each offers slightly different features

    than the others, but they all offer a way to register types and to

    resolve them and their dependencies. To keep the article short, and

    because they are very similar, details of these other containers wont

    be covered here. The difference in usage scenarios is purely

    syntactical and there are plenty of resources available online to showyou how to use them. I will demonstrate an example using one of

    them: Castle Windsor.

    Heres Castle Windsor. In the interest of space, Ill leave out the

    creation of the OrderInfo class:

    WindsorContainer container = new

    WindsorContainer();

    container.Register(Component.For());

    container.Register(

    Component.For().

    ImplementedBy());

    container.Register(Component.For().ImplementedBy());

    container.Register(Component.For().

    ImplementedBy());

    container.Register(Component.For().

    ImplementedBy());

    Commerce commerce =

    container.Resolve();

    commerce.ProcessOrder(orderInfo);

    As you can see, the process is the same, although the API exposed by

    Castle Windsor is very different from that of Unity. Notice that when

    using this container, any class to be resolved needs first to be

    mailto://[email protected]
  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    7/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 7

    reg s ere , nc u ng e ommerce c ass, an no ce a s c ass

    is registered on its own and not associated to any interface.

    Lets look at one more by seeing what the syntax for NInject looks like:

    IKernel container = new StandardKernel();

    container.Bind().

    To();

    container.Bind().To();

    container.Bind().To();

    container.Bind().To();

    Commerce commerce = container.Get();

    commerce.ProcessOrder(orderInfo);

    Microsoft provides another container called the Managed Extensibility

    Framework, or MEF. Although many will argue that MEF is not really a

    DI container, including Microsoft themselves, it does provide the ability

    to serve as one; and quite well. MEF provides the ability to develop

    plug-ins and extensible applications in a simple and consistent manner.

    It provides a container class that stores registrations as well as the

    ability to resolve types and dependencies: the essence of a DI

    container.

    What makes MEF very unique is its ability to discover types insteadof forcing you to list registrations through code at application startup.

    MEF lets you decorate types to be registered and associate them with

    an interface in that decoration. It can then go out and discover said

    types by building a catalog, which it can do in a number of ways. Lets

    take a look at how types are registered in MEF:

    [Export(typeof(IBillingProcessor))]

    [PartCreationPolicy(CreationPolicy.NonShared)]

    public class TestBillingProcessor

    : IBillingProcessor

    {

    void IBillingProcessor.ProcessPayment(

    string customer, string creditCard,

    double price)

    {

    // perform billing gateway processing

    }

    }

    A class dependencies, as in the case of the Commerce class, need

    to be marked in MEF. This can be done with either the

    ImportingConstructorattribute for constructor injection, or with the

    Import attribute for property injection. The MEF version of the

    Commerce class is in Listing 8.

    Note that the Commerce class is also exported. Later, when resolved

    through the container, MEF examines the attributes to satisfy its

    dependencies.

    In order to register the necessary types, you need to create a catalog

    of types. MEF provides several ways of cataloging types but the

    easiest is the assembly catalog. This allows you to point to an

    assembly and let MEF scan it for types that offer type-export

    decorations. You can also combine more than one catalog using an

    aggregate catalog. In this example, you create an aggregate catalog

    but only add one assembly catalog to it.

    AggregateCatalog catalog =

    new AggregateCatalog();

    catalog.Catalogs.Add(new AssemblyCatalog(

    Assembly.GetExecutingAssembly()));

    Container = new CompositionContainer(catalog);

    &

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    8/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 8

    T e Compos t onConta ner c ass s MEF s DI conta ner. Here, I u t a

    catalog from the current assembly, which is where the Commerce

    class and the four process classes reside. Later, to resolve the

    Commerce class and its dependencies, I used the

    GetExportedValue method like this:

    Commerce commerce =

    Container.GetExportedValue();

    commerce.ProcessOrder(orderInfo);

    MEF is included with.NET Framework and its discovery mechanism gives

    it a nice quality over other containers. The trade-off is that your type

    registrations are scattered throughout all your classes in the way of

    attribute decorations. I personally do not consider this a negative

    thing. I like explicit code and MEFs attribute model allows me to

    always know if a class is being used by MEF or not. This is something I

    would not be able to tell if I were using a different DI container.

    Practical Application of Dependency Injection andContainers

    Now, for the fun part. All of this would just be cool code if you dont

    know how to apply it in your applications. Im going to show you how

    to implement a DI container into three types of applications: WPF,

    WebForms, and MVC. With a little effort, you can modify the WPF

    example to work in a Silverlight scenario as well as a Metro app

    scenario.

    The other two examples both apply to ASP.NET, but Ill provide you

    with both since WebForms and MVC differ quite a bit in the way they

    serve views. Ill use MEF as the container but the code I make

    available for download at the end of article also provides examples in

    Unity. Other containers would be a variation of one of the two

    examples.

    WPF

    WPF continues to be Microsofts premier development platform for its

    XAML stack. The other two are Silverlight and Metro apps. With

    certain exceptions here and there, as well some framework differences,

    development on all three platforms is very similar. Views consist of

    XAML markup working in conjunction with code-behind pages. A

    popular pattern that is often associated almost synonymously with

    WPF (all XAML-stack platforms, in fact) is Model-View-ViewModel, or

    MVVM. Ill demonstrate DI in a WPF application that implements the

    MVVM pattern.

    A WPF application has one main view when the application starts up,

    which hosts two other views within it and offers a button to toggle

    between the two. The two views are CustomerListView and

    CustomerView, and the hosting view is MainWindowView. Each of

    the three views has a corresponding view-model class under the same

    name but with a view-model suffix instead ofView.

    A service class provides data models for both the

    CustomerListViewModel and CustomerViewModel classes. Theclass is called CustomerRepository and is responsible for obtaining

    information from a database. The CustomerRepository class

    implements an interface called ICustomerRepository and the view-

    models contain properties of the interface type, not the concrete c lass

    type.

    As you may be able to tell, Ive set the scene for class dependencies

    here. The MainWindowViewModel class has a dependency on the

    other two view-model classes; and each of those two have a

    dependency on an implementation of the ICustomerRepository

    interface. In order to satisfy all dependencies, all class instances need

    to be served up by a DI container. The first order of business is to set

    one up and register types and associations with it.

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    9/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 9

    MEF uses discovery to find types and their associations to interfaces,

    so you have to decorate any class you want to export so that MEF will

    find it. Ill leave out most of the class implementation code for brevity,

    but Ill show the containment of the dependent types to explain

    afterward. Be sure to check the sidebar to see where you can

    download the entire solution of projects.

    The MainWindowViewModel class contains the two other view-

    models and toggles between them using a command and property. The

    class is shown in Listing 9.

    In this class, the dependencies are satisfied using property injection.As you can see, there are two properties of the types of the two

    other view-models and they are both decorated with the Import

    attribute. Later when this class is resolved, instances of those two

    view-models will be injected into these two properties. As you can

    probably guess, both of those view-models will also be exported so

    that MEF discovers and registers them. Because this class will be

    resolved and dependencies injected into them using properties, the

    class will need to be instantiated before its dependencies are injected,

    unlike a constructor injection technique.

    To properly initialize and use this view-model, I need to set the

    CurrentViewModel property to the value _CustomerListViewModel

    property. The problem is that I cant do this in the constructor

    because upon construction, the dependencies have not yet been

    injected. For this kind of situation, MEF gives us theIPartImportsSatisfiedNotification interface. When MEF resolves this

    view-model class, it checks for this interface and if it finds it

    implemented, it executes the OnImportsSatisfied method after it

    finishes injecting dependencies.

    The other two view-model classes will also be exported and contain

    the repository as a dependency. For variation of technique

    demonstration, Ive chosen to use constructor injection in these two

    cases.

    [Export]

    [PartCreationPolicy(CreationPolicy.NonShared)]

    public class CustomerListViewModel

    : view-modelBase{

    [ImportingConstructor]

    public CustomerListViewModel(

    ICustomerRepository customerRepository)

    {

    _CustomersModel =

    customerRepository.GetAll();

    }

    }

    And

    [Export]

    [PartCreationPolicy(CreationPolicy.NonShared)]

    public class CustomerViewModel : view-modelBase{

    [ImportingConstructor]

    public CustomerViewModel(

    ICustomerRepository customerRepository)

    {

    _CustomerModel =

    customerRepository.GetById(1);

    }

    }

    Marking the constructors with the ImportingConstructor attribute

    provides the constructor injection Im looking for. The last thing I need

    is to export the CustomerRepository class and to associate it to the

    ICustomerRe ositor interface.

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    10/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 10

    [Export(typeof(ICustomerRepository))]

    [PartCreationPolicy(CreationPolicy.NonShared)]

    public class CustomerRespository

    : ICustomerRepository

    {

    public Customer GetById(int id) . . .

    public List GetAll() . . .

    public void Update(Customer customer) . . .

    }

    Remember, due to the recursive nature of the DI container type-resolving process, resolving the MainWindowViewModel class later

    will resolve its dependencies, the other view-models. Resolving those

    two classes will resolve their dependencies, the CustomerRepository

    class.

    Now that the classes are set up properly, the WPF application needs

    to discover them so the container can be assembled. The easiest

    place to do this is in the code-behind of the App.xaml file by

    overriding the OnStartup method. This will ensure that it happens at

    application startup.

    public partial class App : Application

    {

    public static CompositionContainer Container;

    protected override void OnStartup( StartupEventArgs e)

    {

    AggregateCatalog catalog =

    new AggregateCatalog();

    catalog.Catalogs.Add(

    new AssemblyCatalog(

    Assembly.GetExecutingAssembly()));

    Container = new CompositionContainer(

    catalog);

    base.OnStartup(e);

    }

    }

    Im also storing the instance of the container in a static property so it

    can be accessed from anywhere in the application if needed.

    Because the MainWindowView window is set up to be the startup

    window, its code-behind class executes when the application starts up

    after the aforementioned OnStartup method executes. The view-

    model for this window needs to be set to the windows DataContext

    property. The other views will have theirs set through data templates

    and a standard view-model-to-Content property technique, but since

    this is the first one, it needs to be done manually. Rather than

    manually instantiating an instance of the MainWindowViewModel

    class, Im going to ask the container for it, and Ill do it in the

    MainWindowView class constructor.

    public MainWindow()

    {

    InitializeComponent();

    MainWindowViewModel view-model =

    App.Container.

    GetExportedValue();

    this.DataContext = view-model;

    }

    This sets the DI wheels into motion. Nowhere else in this project will

    you be instantiating any view-model manually, or any type in which

    view-models are dependent. The application is constructed the way

    modern WPF, Silverlight, and Metro applications are written: using

    containment view-switchin and with view-models mimickin the

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    11/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 1

    containment relationship between views.

    When you write unit tests to test the CustomerRepository, you use

    that actual class so that you can test the database functionality, but

    when you write unit tests to test the view-models, you dont

    necessarily need to access the database. Because the view-models

    depend on a type that implements the ICustomerRepository, you

    can provide view-models with either a test implementation or even

    better Id use a mocking framework.

    MVC

    ASP.NET MVC is a terrific framework that allows us to develop Web

    applications in keeping with good architectural and development

    principles, including separation of concerns, testability, and

    dependency injection.

    Like the view-models in the previous example, the controller classes

    youll use in the MVC example will depend on the same

    ICustomerRepository dependency. The CustomerRepository class

    and the ICustomerRepository interface remain exactly the same as

    in the WPF example, so I wont repeat it here. The HomeController

    class will have its dependency injected using constructor injection and

    can be seen in Listing 10.

    Notice that this class is exported with an identifier string that is the

    same name as the controller class but without the word Controller.Also note that the class is associated with the IController interface.

    This is the case with all other controllers that I write, and because

    there will be many classes associated with the same interface; the

    string identifier becomes important when the controllers get resolved

    later.

    When they architected ASP.NET MVC, they took the idea of decoupled

    types right into the design of the framework. When you write a

    controller class in ASP.NET MVC, a controller factory instantiates the

    class and executes the desired action. The controller factory can be

    unhooked and a replacement put in its place so you can intercept how

    controller classes are served up. Because this controller has

    dependencies that need to be injected into it, it needs to be

    instantiated through the container.

    You have a few choices in the way you implement DI in the MVC

    application, and the first choice is where to setup the container. You

    can do it in the Global.asax.csclass but what you really need to do

    in this file is to hook up a replacement to the default controller

    factory. You need to write a class called MefControllerFactory and

    hook it up in the application startup event of the Global.asax.cs

    class.

    protected void Application_Start()

    {

    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);

    RegisterRoutes(RouteTable.Routes);

    ControllerBuilder.Current

    .SetControllerFactory(

    new MefControllerFactory());

    }

    The line I added to this already-existing event is the last one, where I

    set the controller factory to an instance of the replacement class. You

    will set up the container in the MefControllerFactory class. The

    controller factory is in Listing 11.

    I could have written a controller factory entirely from scratch by

    implementing the IController interface, but it was much easier to

    http://global.asax.cs/http://global.asax.cs/
  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    12/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 12

    method. The constructor contains the code that will discover all of my

    exported types and store the container in a class variable for later

    use. When a controller is requested during a browser query, this class

    will get hit for a controller and it will execute the CreateController

    method. The argument, controllerName , will receive the name of the

    controller as it appeared in the URL used to query the application,

    without the word Controller in it. Thiss why I exported the

    HomeController and identified it with the name, Home. The

    CreateController method queries the controller for a specific type

    that implements the IController interface using the identifier name.

    When the controller class gets resolved, the ICustomerRepository

    dependency will be injected into the constructor argument since Idecorated the constructor with ImportingConstructor. From here,

    its available to any ac tion that needs to use it.

    As in the WPF example, you can write unit tests to test the controller

    act ions and use a mock object to sat isfy the necessary dependencies.

    I want to take advantage of an opportunity presented in this example

    to demonstrate a way you can extend MEF to provide something that

    was not built into it. The controller factory has another available

    method that can be overridden in order to obtain a controller class,

    called GetControllerInstance. This method does not receive a

    controller name in an argument but instead receives a Type. This type

    corresponds to the controller class that needs to be instantiated. This

    seems a whole lot easier because then I can simply export the

    controller, with no need to identify it with a name or associate it with

    the IController interface. The problem is that the MEF container does

    not come equipped with a method to resolve a type given an actual

    Type argument; so Ill extend it by writing an extension method. You

    can see my extension method in Listing 12.

    This extension method adds a method to the container called

    GetExportedValueByType. This method scans the registered types

    and looks for one that matches the Type argument sent into the

    method. Now you can resolve the controllers in the controller factory

    without the need for its name, and you can change the exportation of

    the controller classes to a simple [Export].

    protected override IController

    GetControllerInstance(RequestContext requestContext,

    Type controllerType)

    {

    return _Container.GetExportedValueByType(

    controllerType) as IController;

    }

    Theres a new feature added to MVC 3 called the dependency

    resolver which offers yet another way of resolving controllers. In fact,

    it allows you to resolve many other things in ASP.NET MVC. The full

    code for this article includes examples of its usage, but for the

    purposes of brevity I will not discuss it here.

    WebForms

    The last example of DI usage I will demonstrate involves a technology

    that many think cannot be subject to DI and called it one of its

    shortcomings: ASP.NET WebForms. Unlike ASP.NET MVC, the

    WebForms architecture is one of a much coupled nature. ASPX pages

    are combined with code-behind class and at runtime, the two are

    combined and a virtual page class is created and executed. This is

    where the page life-cycle comes from and why we get several great

    events into which we can inject code. Sadly this also means that the

    code-behind class cannot be instantiated and served by an outside

    influence, since it needs to remain under ASP.NET management the

    entire time. However, like ASP.NET MVC, there is a mechanism in place

    that builds the classes for us and its into that you can tap.

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    13/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 13

    .

    PageHandlerFactory. This class is installed as an HTTP Handler

    Factory and is meant to return an instance of an HTTP Handler; in this

    case, a class that is derivative from System.Web.UI.Page. What you

    can do is override this process with your own handler factory that

    derives from the standard one. By overriding the method that returns

    the Page class, you can call upon the base so that you can obtain

    that page class without interfering with the process, then you can

    inject your dependencies.

    Construction injection is out of the question here because you cannot

    resolve the page class using a container, so you have to resort to

    property injection. MEF lets you do this easily by declaring thedependency properties and decorating them with the Import attribute.

    The dependency class in this case remains the CustomerRepository

    class and its configuration for MEF compliance remains the same as in

    the two previous examples. The ASPX pages code-behind class does

    not need to get decorated with anything at the c lass level, since it will

    not be served through the container, only at the property level for the

    dependencies it may contain.

    public partial class Customers

    : System.Web.UI.Page

    {

    [Import]

    ICustomerRepository _CustomerRepository;

    protected void Page_Load(object sender,

    EventArgs e)

    {

    grdCustomers.DataSource =

    _CustomerRepository.GetAll();

    grdCustomers.DataBind();

    }

    }

    Ill show you how to resolve that class dependencies in a few minutes,

    but first you have to configure the container in the WebForms

    application.

    As in the MVC example, you can go to the Application_Start event in

    the Global.asax.csfile to set up the container.

    protected void Application_Start(object sender,

    EventArgs e)

    {

    AggregateCatalog catalog =

    new AggregateCatalog();

    catalog.Catalogs.Add(new AssemblyCatalog(

    Assembly.GetExecutingAssembly()));

    CompositionContainer container =

    new CompositionContainer(catalog);

    Application["Container"] = container;

    }

    Also like the previous example, youll use the Application store to

    hang on to the container. Next, you have to create a class that will

    replace the PageHandlerFactory class.

    Ive created a class called MefPageHandlerFactory, which will

    override the GetHandler method and obtain the Page class by calling

    on the base. Listing 13 shows the factory class.

    After youve obtained the page class, youll use a feature that MEF

    provides. By calling the SatisfyImportsOnce method, youre telling

    MEF to run the class sent into the argument through the resolve

    process and attempt to resolve any properties it finds decorated with

    the Import attribute. When the page is returned at the end of the

    method, it will be equipped with instances of the proper classes in its

    http://global.asax.cs/http://system.web.ui/http://system.web.ui/
  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    14/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 14

    .

    The last thing you need to do is install the new handler factory in the

    web.config file by assigning it as the handler to be used for anything

    with an aspx extension.

    Unfortunately, unit-testing WebForms code-behind pages is next to

    impossible as the class cannot be instantiated on its own. This remains

    one of WebForms shortcomings.

    That being said, I think I need to say something in defense of

    WebForms. Business code should be written so it can be tested on its

    own, regardless of the client implementing it. ASP.NET MVC lets us unit

    test controller actions but that does not mean this should serve as the

    test for your business logic. Controller actions return a certain result

    based on input arguments and thats what should be tested by unit

    tests, not that the customer was saved properly. If you design

    applications to accommodate this, the lack of ability to test a

    WebForms code-behind class will seem a little less significant and

    WebForms may be able to retain some of the glory it once carried as afirst class development platform for Web applications. I say this as an

    active developer in both the WebForms and MVC platforms.

    Conclusion

    As you can see, dependency injection solves several problem areas in

    development. It allows you to decouple code components from one

    another and it lets you stop worrying about instantiating classes to

    send into other classes. Solving these two problems also sets up your

    software for easy testability later.

    There are many elements of DI that I couldnt cover in this article.

    Among them is the resolving multiple implementations of an interface

    as well as defining which of several registered implementations gets

    resolved, which is possible through configuration files. Most containers

    provide both of these features, each in its own variety.

    I also couldnt cover every container out there. Besides MEF, Unity,

    NInject, and Castle Windsor, there are also StructureMap and

    Spring.NET. I apologize to the developers of the latter two for not

    providing coverage within this article but Ill go on record as saying

    that both StructureMap and Spring.NET are first-class citizens in the

    DI world and top-shelf products.

    The examples in this article should give you a great head-start on

    using dependency injection. The three scenarios should also serve as a

    good kick-off point for just about any application you are writing.

    Whether youre using a Microsoft container or a third-party one, using

    DI in your applications will ensure that youre writing decoupled,manageable, and testable components, and also very importantly, its

    really, really cool.

    Miguel Castro

    Listing 1: OrderInfo class

    public class OrderInfo

    {

    public string CustomerName { get; set; }

    public string Email { get; set; }

    public string Product { get; set; }

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    15/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 15

    public string CreditCard { get; set; }

    }

    Listing 2: The four process classes

    public class BillingProcessor

    {

    public void ProcessPayment(string customer,

    string creditCard, double price)

    { // perform billing gateway processing

    }

    }

    public class Customer

    {

    public void UpdateCustomerOrder(string customer,

    string product)

    {

    // update customer record with purchase

    }

    }

    public class Notifier

    { public void SendReceipt(OrderInfo orderInfo)

    {

    // send email to customer with receipt

    }

    }

    public class Logger

    {

    public void Log(string message)

    {

    // log message to log file

    }

    }

    Listing 3: Commerce class

    public class Commerce

    {

    public Commerce(BillingProcessor billingProcessor,

    Customer customer,

    Notifier notifier,

    Logger logger)

    {

    _BillingProcessor = billingProcessor;

    _Customer = customer;

    _Notifier = notifier;

    _Logger = logger;

    }

    BillingProcessor _BillingProcessor;

    Customer _Customer;

    Notifier _Notifier;

    Logger _Logger;

    public void ProcessOrder(OrderInfo orderInfo)

    {

    _BillingProcessor.ProcessPayment(

    orderInfo.CustomerName,

    orderInfo.CreditCard,

    orderInfo.Price);

    _Logger.Log("Billing processed");

    _Customer.UpdateCustomerOrder(

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    16/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 16

    orderInfo.CustomerName,

    orderInfo.Product);

    _Logger.Log("Customer updated");

    _Notifier.SendReceipt(orderInfo);

    _Logger.Log("Receipt sent");

    }

    }

    Listing 4: Process classes refactored to interfaces

    public interface IBillingProcessor{

    void ProcessPayment(string customer, string creditCard,

    double price);

    }

    public interface ICustomer

    {

    void UpdateCustomerOrder(string customer,

    string product);

    }

    public interface INotifier

    {

    void SendReceipt(OrderInfo orderInfo);

    }

    public interface ILogger

    { void Log(string message);

    }

    Listing 5: Commerce class rewrite using interfaces

    public class Commerce

    {

    public Commerce(IBillingProcessor billingProcessor,

    ICustomer customer,

    INotifier notifier,

    ILogger logger)

    {

    _BillingProcessor = billingProcessor;_Customer = customer;

    _Notifier = notifier;

    _Logger = logger;

    }

    IBillingProcessor _BillingProcessor;

    ICustomer _Customer;

    INotifier _Notifier;

    ILogger _Logger;

    public void ProcessOrder(OrderInfo orderInfo)

    {

    _BillingProcessor.ProcessPayment(

    orderInfo.CustomerName, orderInfo.CreditCard,

    orderInfo.Price);_Logger.Log("Billing processed");

    _Customer.UpdateCustomerOrder(orderInfo.CustomerName,

    orderInfo.Product);

    _Logger.Log("Customer updated");

    _Notifier.SendReceipt(orderInfo);

    _Logger.Log("Receipt sent");

    }

    }

    Listing 6: My makeshift DI container

    public class Container

    {

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    17/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 17

    public Container()

    {

    _Registrations = new List();

    }

    public void Register()

    where U : class, new()

    {

    Type abstractionType = typeof(T);

    Type concreteType = typeof(U);

    if (!abstractionType.IsInterface) throw new ApplicationException(

    "First generic argument must be an

    interface type.");

    _Registrations.Add(new ContainerItem()

    {

    AbstractionType = abstractionType,

    ConcreteType = concreteType

    });

    }

    List _Registrations;

    }

    Listing 7: Modified CreateType function and support code

    public T CreateType() where T : class

    {

    Type type = typeof(T);

    return (T)GetConcreteType(type);

    }

    object GetConcreteType(Type typeToResolve)

    {

    ContainerItem containerItem =

    _Registrations.Where(item =>

    item.AbstractionType.Equals(

    typeToResolve)).FirstOrDefault();

    if (containerItem != null)

    return GetTypeInstance(containerItem.ConcreteType);

    else

    return GetTypeInstance(typeToResolve);

    }

    object GetTypeInstance(Type type)

    {

    object instance = null;

    ConstructorInfo[] constructors = type.GetConstructors();

    if (constructors.Length > 0)

    {

    ConstructorInfo constructor = constructors[0];

    List constructorArguments =

    new List();

    ParameterInfo[] parameters =

    constructor.GetParameters();

    foreach (ParameterInfo parameter in parameters)

    {

    object parameterInstance = null;

    if (parameter.ParameterType.IsInterface)

    parameterInstance = GetConcreteType(

    parameter.ParameterType);

    constructorArguments.Add(parameterInstance);

    }

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    18/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 18

    instance = Activator.CreateInstance(

    type, constructorArguments.ToArray());

    }

    return instance;

    }

    Listing 8: MEF-aware Commerce class

    [Export]

    [PartCreationPolicy(CreationPolicy.NonShared)]

    public class Commerce

    {

    [ImportingConstructor]

    public Commerce(IBillingProcessor billingProcessor,

    ICustomer customer, INotifier notifier,

    ILogger logger)

    {

    _BillingProcessor = billingProcessor;

    _Customer = customer;

    _Notifier = notifier;

    _Logger = logger;

    }

    IBillingProcessor _BillingProcessor;

    OR

    public Commerce()

    {

    }

    [Import]

    IBillingProcessor _BillingProcessor;

    }

    Listing 9: MainWindowViewModel class

    [Export]

    [PartCreationPolicy(CreationPolicy.NonShared)]

    public class MainWindowViewModel

    ViewModelBase, IPartImportsSatisfiedNotification

    {

    [Import]

    CustomerListViewModel _CustomerListViewModel;

    [Import]

    CustomerViewModel _CustomerViewModel;

    ViewModelBase _CurrentViewModel;

    public ICommand ToggleViewCommand { get; private set; }

    public ViewModelBase CurrentViewModel

    {

    get { return _CurrentViewModel; }

    set

    {

    _CurrentViewModel = value;

    OnPropertyChanged("CurrentViewModel");

    }

    }

    public void OnImportsSatisfied()

    {

    =

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    19/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    www.code-magazine.com/articleprint.aspx?quickid=1210031&printmode=true 19

    _

    }

    }

    Listing 10: MVC controller

    [Export("Home", typeof(IController))]

    [PartCreationPolicy(CreationPolicy.NonShared)]

    public class HomeController : Controller

    {

    [ImportingConstructor]

    public HomeController(

    ICustomerRepository customerRepository)

    {

    _CustomerRepository = customerRepository;

    }

    ICustomerRepository _CustomerRepository;

    public ActionResult Customers()

    {

    IEnumerable customers =

    _CustomerRepository.GetAll();

    return View(customers);

    }

    }

    Listing 11: MVC controller factory

    public class MefControllerFactory : DefaultControllerFactory

    {

    private CompositionContainer _Container;

    public MefControllerFactory()

    {

    AggregateCatalog catalog = new AggregateCatalog();

    catalog.Catalogs.Add(

    new AssemblyCatalog(

    Assembly.GetExecutingAssembly()));_Container = new CompositionContainer(catalog);

    }

    public override IController CreateController(

    RequestContext requestContext, string controllerName)

    {

    return _Container.GetExportedValue(

    controllerName);

    }

    }

    Listing 12: MEF extension method

    public static object GetExportedValueByType( this CompositionContainer container, Type type)

    {

    foreach (var PartDef in container.Catalog.Parts)

    {

    foreach (var ExportDef in PartDef.ExportDefinitions)

    {

    if (ExportDef.ContractName == type.FullName)

    {

    var contract = AttributedModelServices.

    GetContractName(type);

    var definition =

    new ContractBasedImportDefinition(

    contract, contract, null,

    ImportCardinality.ExactlyOne,

  • 7/30/2019 CODE Magazine - Article_ Understanding Dependency Injection and Those Pesky Containers

    20/20

    9/2/13 CODE Magazine - Article: Understanding Dependency Injection and Those Pesky Containers

    a se, a se, rea on o cy. ny ;

    return container.GetExports(definition).

    FirstOrDefault().Value;

    }

    }

    }

    return null;

    }

    Listing 13: WebForms Page Handler Factory

    public class MefPageHandlerFactory : PageHandlerFactory

    {

    public override IHttpHandler GetHandler(

    HttpContext context,

    string requestType,

    string virtualPath,

    string path)

    {

    Page page = base.GetHandler(

    context, requestType, virtualPath, path)

    as Page;

    if (page == null) return page;

    CompositionContainer container =

    context.Application["Container"]

    as CompositionContainer;

    container.SatisfyImportsOnce(page);

    return page;

    }

    }