Export (0) Print
Expand All

Walkthrough: The Unity StopLight QuickStart

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The latest Unity Application Block information can be found at the Unity Application Block site.

The StopLight QuickStart demonstrates the ways that you can use the Unity Application Block and the Unity container in your applications. The user interface is a simple Windows Forms application that displays the three colors of a "stop light" or "traffic light"—it shows red, yellow, and green, in turn, for specified periods. You can configure the display periods for each color. Figure 1 shows the user interface.

Ff650554.dfa80441-1c57-4529-a5aa-20f5e2d2aa7d(en-us,PandP.10).png

Figure 1
The user interface of the StopLight QuickStart

The StopLight QuickStart demonstrates the following features of the Unity Application Block:

Figure 2 shows the classes and architecture of the StopLight QuickStart application.

Ff650554.889bcdea-6f02-4c20-856d-0e97ee04e29b(en-us,PandP.10).png

Figure 2
The architecture, classes, and structure of the StopLight QuickStart

The StopLight QuickStart uses two services that the Unity container maps from interfaces to concrete service implementations. These two services are injected into classes that require them automatically when unity creates instances of the class.

The two interfaces are ILogger, which Unity maps to the concrete service class named TraceLogger, and IStoplightTimer, which Unity maps to the concrete service class named RealTimeTimer. The mapping registration occurs in the Program file that executes when the application starts. It uses the following code.

IUnityContainer container = new UnityContainer()
                            .RegisterType<ILogger, TraceLogger>()
                            .RegisterType<IStoplightTimer, RealTimeTimer>();

This sets up two default (unnamed) mappings so that requests to the container for the ILogger interface will return a new instance of the TraceLogger component and requests to the container for the IStoplightTimer interface will return a new instance of the RealTimeTimer component.


Ff650554.note(en-us,PandP.10).gifNote:
The TraceLogger component (in the ServiceImplementations folder) exposes a single method named Write that writes a specified message to the application's current System.Diagnostics.Trace instance.

The RealTimeTimer component is a "single-shot" timer implemented in the file RealTimeTimer (in the ServiceImplementations folder). It exposes a property named Duration (in milliseconds), a Start method, and it raises the OnExpired event when the timer reaches the specified duration.


After registering the required mappings, the code must force dependency injection to be applied to the child objects the application uses. The parent object for the application is the Windows Forms user interface class named StoplightForm. To ensure that all dependent objects are injected, the code in the Program class instantiates the StoplightForm using the Resolve method of the Unity container, as shown here.

Application.Run(container.Resolve<StoplightForm>());

The Run method of the Application class accepts as a parameter an object that is the class to execute. The Resolve method of the Unity container generates an instance of the StoplightForm class, applying dependency injection to all child classes to create or reference the objects these child classes require.

When the program starts, it loads and displays the user interface—the Windows Form named StoplightForm. This form implements the view for the Model-View-Presenter (MVP) pattern, so it must expose a property that is a reference to its associated presenter. To obtain a reference to its presenter, a class named StoplightPresenter, the form uses property (setter) injection by applying the Dependency attribute to the property, as show in this code.

public partial class StoplightForm : Form, IStoplightView
{
  private StoplightPresenter presenter;

  [Dependency]
  public StoplightPresenter Presenter
  {
    get { return presenter; }
    set
    {
      presenter = value;
      presenter.SetView(this);
    }
  }
  ...

This ensures that Unity will create the presenter before it creates and displays the view (the StoplightForm form). The dependent class type for dependency injection is the concrete class StoplightPresenter, so the Unity container can create this object without requiring a mapping in the container.

The view exposes event handlers that the presenter can use to manipulate the controls on the form and access the values.

The presenter for the user interface, the class named StoplightPresenter, requires an instance of the class named Stoplight that represents the set of colors and methods of a real stop light. The Stoplight class uses an enumeration of the three colors (red, yellow, and green), exposes the Next method that the application can use to change the colors in a predefined sequence, and raises the StoplightChangedHandler event when a color change occurs. The argument for this event is an instance of class named LightChangedEventArgs that exposes the current color.

To obtain an instance of this class, the StoplightPresenter exposes it as a property and applies the Dependency attribute to the property, as shown in the following code.

private Stoplight stoplight; 

[Dependency]
public Stoplight Stoplight
{
  get { return stoplight; }
  set { stoplight = value; }
}

The dependent class type for dependency injection is the concrete class Stoplight, so the Unity container can create this object without requiring a mapping in the container.

The presenter also has a dependency on the StoplightSchedule class, which maintains references to the StoplightTimer and ILogger, exposes methods to update the durations for the colors and force a change to the next color, and responds to the OnTimerExpired event raised by the RealTimeTimer class.

To get a reference to a new instance of the StoplightSchedule class, the StoplightPresenter exposes it as a property named Schedule and applies the Dependency attribute to the property, as shown in the following code.

private StoplightSchedule schedule; 

[Dependency]
public StoplightSchedule Schedule
{
  get { return schedule; }
  set { schedule = value; }
}

Again, the dependent type is a concrete class, in this case the StoplightSchedule class, and so the Unity container can create this object without requiring a mapping in the container.

The Stoplight and StoplightSchedule classes have dependencies that are not concrete classes. Both of these classes have a dependency on one of the concrete implementations of the ILogger interface—either the NullLogger or the TraceLogger. At run time, the code can choose which concrete class to instantiate. It can use any class that implements the ILogger interface, which defines just the single method Write that takes a message and writes it to the appropriate output.

This is an example of a pluggable architecture. The actual class chosen at run time, and injected into the application, depends on the mapping in the Unity container. The QuickStart maps the ILogger interface to the concrete type TraceLogger using the method RegisterType<ILogger, TraceLogger>() in the main Program class. Therefore, to use a different concrete implementation, the developer just has to change the mapping. For example, to use a new class ReallyFastLogger, the developer would just change the mapping to RegisterType<ILogger, ReallyFastLogger>().

In addition, by using a configuration file to populate the Unity container or reading the configuration information from another source such as a database, the developer allows the user to change the actual concrete logging class without requiring recompilation of the application code.

The Stoplight and StoplightSchedule classes force injection of the currently mapped logger class by exposing it as a property named Logger (of type ILogger) that has the Dependency attribute applied, as shown in the following code.

private ILogger logger; 

[Dependency]
public ILogger Logger
{
get { return logger; }
  set { logger = value; }
}


Show:
© 2014 Microsoft