Injecting Xaml with Unity Application Block using Markup Extensions


Notes: This article assumes that you are familiar or started playing with a Unity Application Block. I won’t dwell on describing it’s architecture or manuals so please refer to the link mentioned for more details.

Today I’ve got another drop of Unity Application Block and decided to play with it in the scope of WPF to see what ideas might appear and how flexible Unity may be dealing with Xaml. For testing purposes I’ve decided to get Unity Container being referenced totally within the markup without code behind usage. Additionally I wanted to get some dummy UI elements built up by the container and injected into the page. It took me approximately 2 hours of playing and I must say I was quite satisfied with the results.

I’ll be giving just the pure idea to be elaborated without any fancy visual stuff. That’s up to you guys to get anything worth usable from it.

Common Unity Container can be configured in two ways. It is either manual configuration and initialization at code behind or using configuration file ("App.config" or "Web.config"). Of course for keeping experiment clear I’ve chosen the latter one – application configuration.

Here’s a simple snippet that can be found in the documentation file

<?xml version="1.0" encoding="utf-8" ?>
<
configuration>
  <
configSections>
    <
section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration, Version=1.0.0.0,
                 Culture=neutral, PublicKeyToken=31bf3856ad364e35
" />
  </
configSections>
 
  <
unity>
    <
typeAliases/>
   
    <
containers>
      <
container name="containerOne">
        <
types/>
      </
container>
    </
containers>
   
  </
unity>
</
configuration>

So we declare common Unity section called "unity" and one container called "containerOne". Type aliases and container types will be described later on.

Next step is bringing a container to the upper level from code behind to markup. We need something declared within the page that can be referenced to from the other elements. It can be achieved either by declaring a static resource or introducing some bridge control wrapping your Container. I’ve chosen the latter one because it might give me possibilities easy accessing my container either from xaml or code behind depending on situation and complexity of requirements.

Unity Container Provider

Simple initialization of Unity Container from code behind looks like the following

IUnityContainer container = new UnityContainer();
UnityConfigurationSection section =
  (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers["containerOne"].Configure(container);

So we need to know the section name and container name to create and configure properly our container. This means that theoretically we could have some element on the page like following:

<ContainerProvider Name="defaultProvider" Section="unity" Container="containerOne"/>

Such control doesn’t require any UI representation and can serve like data provider similar to Windows Forms Designer age 😉

To save your time for future enhancements there’s quite a good reason providing additional facility that will populate any control with a Unity Container (if appropriate property is supported by control) and so giving you possibility integrating the logic in more complex layouts and implementations.

This is where Markup Extensions come.

Unity Configuration Extension (UnityConfiguration.cs)

using System;
using System.Configuration;
using System.Windows.Markup;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace UnityTesting1
{
  [MarkupExtensionReturnType(typeof(IUnityContainer))]
  public class UnityConfiguration : MarkupExtension
  {
    #region Properties
    [ConstructorArgument("section")]
    public string Section { get; set; }

    [ConstructorArgument("container")]
    public string Container { get; set; } 
    #endregion

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
      IUnityContainer container = new UnityContainer();
      UnityConfigurationSection section = 
        (UnityConfigurationSection)ConfigurationManager.GetSection(Section);
      section.Containers[Container].Configure(container);
      return container;
    }

    #region ctors
    public UnityConfiguration()
    {
    }

    public UnityConfiguration(string section, string container)
    {
      this.Section = section;
      this.Container = container;
    } 
    #endregion
  }
}

Here I’ve introduced a very simple markup extension that will provide our elements with a Unity container taken from application configuration. It has two properties: "Section" for section name and "Container" for referencing some required container within the configuration section.

For getting more really good details on markup extensions you may refer to Rob Relyea’s blog

So assuming our container provider has a dedicated property for storing a container it can now be declared like the following:

<ContainerProvider
      x:Name="defaultProvider"
      Container="{UnityConfiguration Section=unity, Container=containerOne}"/>

Guess it’s a more convenient way using markup extension in this case because as you’ve might understood that it can be applied to any object that holds IUnityContainer child as a property.

Using extension above our container holder source becomes extremely simple:

Container Provider Contract (IContainerProvider.cs)

public interface IContainerProvider
{
  IUnityContainer Container { get; }
}

This is mainly for future extensibility and flexibility.

Container Provider (ContanerProvider.cs)

public class ContainerProvider : FrameworkElement, IContainerProvider
{    
  public IUnityContainer Container { get; set; }
}

As you can see we are having more lookless stub I think than fully featured control. You can get rid of it or introduce new features at any time.

Just to ensure injection methods works fine and to have a stab for future implementations I’ve introduced a dummy service called "ContentResolver" that it to be used as a singleton and take part in the entities buildup process. It won’t do a lot but demonstrate the possible usage for flexible initialization of our UI elements.

Content Resolver Contract (IContractResolver.cs)

public interface IContentResolver
  {
    string GetName();
  }

Content Resolver (ContentResolver.cs)

public class ContentResolver : IContentResolver
  {
    #region IPersonResolver Members

    public string GetName()
    {
      //return Guid.NewGuid().ToString("B");
      return DateTime.Now.ToLongTimeString();
    }

    #endregion
  }

Our following controls will be taking the data via this service. Again reminding that this is absolutely optional and can be skipped.

Next step is providing some UI elements we will build up via our Unity container. I’ll give two samples: Image and ListBox controls just to catch the main idea. Our sample controls will be exposing IContent contract for flexibility purposes

Content Contract (IContent.cs)

public interface IContent
{
}

I will use it mainly for identification and generalization purposes so the contract doesn’t have any members.

Image Content (ImageContent.cs)

public class ImageContent : Control, IContent
{
  public string ImagePath { get; set; }
  public string Text { get; set; }

  static ImageContent()
  {
    DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageContent), 
      new FrameworkPropertyMetadata(typeof(ImageContent)));
  }
  
  [InjectionMethod]
  public void Initialize(IContentResolver resolver)
  {      
    this.Text = resolver.GetName();
    this.ImagePath = "Images/gear.png";
  }
}

Our simple control has two properties "ImagePath" and "Text". Normally they should be Dependency Properties but I’ve simplified it to have a compact view of general info 😉 It has a customized template (see attached sources for more details).

Also you can see the injected method that provides basic initialization of a control. Here you normally insert more efficient stuff required for controls and taken from external singleton based (in my implementation) service.

ListBox Content (ListBoxContent.cs)

public class ListBoxContent : ListBox, IContent
{
  public ListBoxContent()
  {
    this.Items.Add("One");
    this.Items.Add("Two");
    this.Items.Add("Three");
    this.Items.Add("Four");
    this.Items.Add("Five");
  }
}

Next control represents a common ListBox. It doesn’t require any initialization injection and has no overridden templates.

Actually you can avoid creating wrapper classes for standard controls and this is what normally you will do in a real-life development. As this will require using Activator class and dynamic Type instantiation I’ve decided to move the simple way to keep the code and configuration file more understandable. But keep in mind that it’s absolutely possible and there’s no problems implementing that for you in future.

Configuration file (App.config)

Here’s how our final configuration file that we’ll be using across the sample application:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
              type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration, Version=1.0.0.0,
                 Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>

  <unity>

    <typeAliases>

      <typeAlias alias="singleton" 
                 type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, 
                 Microsoft.Practices.Unity" />
      
      <typeAlias alias="IContentResolver" 
                 type="UnityTesting1.IContentResolver, UnityTesting1"/>
      <typeAlias alias="ContentResolver" 
                 type="UnityTesting1.ContentResolver, UnityTesting1"/>
      
      <typeAlias alias="IContent" 
                 type="UnityTesting1.IContent, UnityTesting1"/>
      <typeAlias alias="ImageContent" 
                 type="UnityTesting1.ImageContent, UnityTesting1"/>
      <typeAlias alias="ListBoxContent" 
                 type="UnityTesting1.ListBoxContent, UnityTesting1"/>
      
    </typeAliases>

    <containers>
      <container name="containerOne">
        <types>

          <type type="IContentResolver" mapTo="ContentResolver">
            <lifetime type="singleton" />
          </type>

          <type type="IContent" mapTo="ImageContent" name="UnityImage"/>
          <type type="IContent" mapTo="ListBoxContent" name="UnityList"/>
          
        </types>
        </container>
    </containers>

  </unity>

</configuration>

I’ve created all required aliases and filled container with appropriate types. Our Image and ListBox content will be accessed using "UnityImage" and "UnityList" names.

So if we were using the code behind approach we would resolve our "UnityList" using the following line:

IContent content = container.Resolve<IContent>("UnityList");

This returns as an object of ListBoxContent type that is actually a subclass of ListBox and so UIElement that can be easily added to the visual tree of a panel, canvas or whatever.

Analyzing content creation you can see that generally for creating our control we need initialized Unity container and name of the element to be resolved. This can be theoretically put to xaml in the following way:

<SomeElement Container="defaultProvider" Dependency="UnityList"/>

We have already discussed container provider element so how exactly we can reference it in the code and what else should be created that can cover all our content controls? We definitely need another markup extension that will give us all the required possibilities…

Unity Reference Markup Extension (UnityReference.cs)

[MarkupExtensionReturnType(typeof(UIElement))]
public class UnityReference : MarkupExtension
{
  #region Properties
  [ConstructorArgument("container")]
  public string Container { get; set; }

  [ConstructorArgument("dependency")]
  public string Dependency { get; set; } 
  #endregion

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    IProvideValueTarget ipvt = 
      (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
    FrameworkElement fe = ipvt.TargetObject as FrameworkElement;
    FrameworkContentElement fce = ipvt.TargetObject as FrameworkContentElement;

    if (fe != null)
    {        
      IContainerProvider containerProvider = 
        fe.FindName(Container) as IContainerProvider;
      if (containerProvider == null)
        throw new Exception("IContainerProvider not found!");

      return containerProvider.Container.Resolve<IContent>(this.Dependency);
    }
    else if (fce != null)
    {
      IContainerProvider containerProvider = 
        fce.FindName(Container) as IContainerProvider;
      if (containerProvider == null)
        throw new Exception("IContainerProvider not found!");

      return containerProvider.Container.Resolve<IContent>(this.Dependency);
    }
    else
      throw new Exception("Container " + Container + " cannot be resolved!");
  }

  #region ctors
  public UnityReference()
  {
  }

  public UnityReference(string container, string dependency)
  {
    this.Container = container;
    this.Dependency = dependency;
  } 
  #endregion
}

Here we’ve introduced a unified approach for presenting our Unity based controls using a simple (hope so) markup extension. Next it becomes possible using the following declaration in a xaml:

<UnityReference Container="defaultProvider" Dependency="UnityList"/>

As markup extension turns into the UIElement resolved within the "defaultProvider" container holder we get a fully functional ListBoxContent control at the end of processing.

Finally here comes the sample application that can be constructed of such blocks

<Window x:Class="UnityTesting1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:this="clr-namespace:UnityTesting1"
    Title="Window1" Height="600" Width="800">    
    
    <DockPanel LastChildFill="True">
        
        <this:ContainerProvider 
            x:Name="defaultProvider" 
            Container="{this:UnityConfiguration 
                Section=unity, 
                Container=containerOne}"/>
        
        <StackPanel DockPanel.Dock="Left" 
                    Width="200" 
                    Background="AliceBlue">            
            <this:UnityReference 
                Container="defaultProvider" 
                Dependency="UnityList"/>
        </StackPanel>
        <Canvas x:Name="canvas">            
            <Button Width="100" 
                    Content="{this:UnityReference 
                        Container=defaultProvider, 
                        Dependency=UnityImage}"/>
        </Canvas>
    </DockPanel>    
    
</Window>

image

The source code for the article can be found here

Advertisements

2 thoughts on “Injecting Xaml with Unity Application Block using Markup Extensions

  1. Thanks for the feedback. I’d recommend you paying more attention to the second part where I’m dealing with standard WPF controls and delegate content to the element being injected.
    Part 3 will cover attached properties and bindings delegation so stay on the line 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s