AOP and IOC in WCF 4.0 with Enterprise Library 5 and AppFabric, part 1

Hello,

I would like to share with you how we develop AOP and IOC in WCF 4.0 with the EntLib 5 (unity and policy injection), and how we log data in AppFabric. In this first post I will explain how to configure WCF in order to use unity to resolve the class that implement the service contract interface.

First of all we need to create a behaviour in WCF in order to generate the instance from the unity container and not directly. This is done using three classes.

First we need the configuration element, this is the easy one:

///
/// Creates a behaviour for forcing wcf to use unity.
///
public class UnityBehaviorExtensionElement : System.ServiceModel.Configuration.BehaviorExtensionElement
{
public UnityBehaviorExtensionElement()
{
}

public override Type BehaviorType
{
//Returns the type of UnityServiceBehavior
get { return typeof(UnityServiceBehavior); }
}

protected override object CreateBehavior()
{
return new UnityServiceBehavior(); //<-- add the behaviour
}
}

Ok, now we add a behaviour to the wcf service, what is inside that behaviour? In the behaviour the Unity container is created and a new instance provider is assigned to the endpoint.

///
/// Creates a behaviour that takes the service instance from an unity container.
///
public class UnityServiceBehavior : System.ServiceModel.Description.IServiceBehavior
{
///
/// The Instance Provider Reference
///
private UnityInstanceProvider InstanceProvider { get; set; }

public UnityServiceBehavior()
{
//Creates the UnityInstanceProvider
this.InstanceProvider = new UnityInstanceProvider();

this.InstanceProvider.UnityContainer = new UnityContainer();
this.InstanceProvider.UnityContainer.AddNewExtension();
this.InstanceProvider.UnityContainer.AddNewExtension();

this.ConfigureUnityContainer(this.InstanceProvider.UnityContainer);

}

private void ConfigureUnityContainer(IUnityContainer unityContainer)
{
//Loads the Unity Section Handler and its configuration
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

//Configures the container
section.Configure(unityContainer);
}

public void ApplyDispatchBehavior(System.ServiceModel.Description.ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;

if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
//Indicates to instance provider the Service Type
this.InstanceProvider.ServiceType = serviceDescription.ServiceType;

//Sets the UnityInstanceProvider Foreach EndpointDispatcher
ed.DispatchRuntime.InstanceProvider = this.InstanceProvider;
}
}
}
}

So now we only need that instance provider. It just take the interface with the ServiceContractAttribute and resolve with that the creation of the new service object.

public object GetInstance(System.ServiceModel.InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
{
//Check if the container is available
if (this.UnityContainer != null)
{
/*
* Creates the service instance using Unity App. Block (DI and IoC)
* */

var interWithServiceContractTag = this.ServiceType.GetInterfaces().First(i => i.GetCustomAttributes(true).Any(ca => ca.ToString()=="System.ServiceModel.ServiceContractAttribute"));
var o = this.UnityContainer.Resolve(interWithServiceContractTag);
// var o = this.UnityContainer.Resolve(this.ServiceType.GetInterfaces()[0]);

return o;

}

return instanceContext;
}

how do we tell wcf to use all this stuff? The easiest way is through configuration in the web.config: First we define the extension:

<extensions> 
      <behaviorExtensions>
        <add name="UnityWCF" type="Sample.WCF.Extensions.Unity.UnityBehaviorExtensionElement, TracingAndLogging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </behaviorExtensions>
    </extensions>

And later we apply that behaviour:

 <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false" />
          <UnityWCF />
          <etwTracking profileName="HealthMonitoring Tracking Profile" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

Now we only need to configure the unity container to resolve the type that implements the interface exposed:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension prefix="" type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    <namespace name="TracingAndLogging" />
    <assembly name="TracingAndLogging" />
    <container>
      <register type="ISvcFake" mapTo="SvcFake">
        <interceptor type="InterfaceInterceptor" />
        <policyInjection />
      </register>
    </container>
  </unity>

With all of this we have the WCF created through an IoC container and with policy injection (AoP) capatibilities.

In the next post I will explain how to write tracing and logging info in the AppFabric.

Here is the code.

Advertisements

6 comments

  1. George · · Reply

    Can you explan how is that AOP? AOP has interception like IOC, but DI!=AOP

    1. Well, AoP intercepts the calls (cut-points) and sets an advice in that part. IoC and DI is about creating types.

  2. Hi Pablo! First of all let me thank you for nice and clean article.
    Have you tried to use autofac instead of Unity? Maybe some other more “light” IoCs?
    Thanks!

    1. You are welcome!!

      I havent tried with other,but it should work even faster

      1. Is there any possibility to configure unity bindings (interface->implementation) in code-behind instead of service configuration?

  3. tillias :

    Is there any possibility to configure unity bindings (interface->implementation) in code-behind instead of service configuration?

    yes, you can

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

%d bloggers like this: