Wcf and Unity Revisited

UPDATE: 4/23/2012

9 months later, things continue to change. In this post I refer to “default wiring”. I now recognize that is not a good idea as it will most often result in your project requiring additional assemblies. The additional assemblies will contain the dependencies that you hard-coded. You shouldn’t hard code them even if it’s more convenient. If you need a convenience method, then create one at the application level perhaps, not the API level.

ORIGINAL POST

A couple years ago, when working on a service bus, I did a blog post on integrating unity and Wcf:

https://hamletcode.wordpress.com/2009/09/02/injecting-into-a-wcf-service/

It’s a disaster of a post, but is hit frequently for some reason. That was all about figuring out how to do it and blabbering on as I did so.

Well, I had to implement it again, so I thought I’d post the same information again more concisely, updated (very slightly) for Asp.Net MVC 3.

Why Bother?

Unity Is an IOC. IOC encourages loose coupling and helps keep things very testable. It allows you to wire up your objects at runtime rather than at code time. If you need to swap out one implementation with another (which makes your application more extensible), then you can do so via configuration.

I cringe quite a bit. Usually the cringing is prompted by static variables and singletons that are used to provide common functionality to a bunch of classes. In some cases, it’s the best way to do it, and it is often simpler. But, simpler isn’t always better. Simpler often results in less flexibility.

Here’s an example of something that I had to do, because the IOC wasn’t in place:

 1: /// <summary>

 2: /// I hate doing this, but lacking an IOC, we'll have to tolerate it for now

 3: /// </summary>

 4: private static readonly Commands defaultCommands = CommandXmlParser.Parse(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Commands.xml"));

 5: private readonly Commands commands;

 6:

 7: /// <summary>

 8: /// Initializes a new instance of the Command service, using the default

 9: /// static commands.

 10: /// </summary>

 11: public CommandService()

 12:     : this(CommandService.defaultCommands)

 13: {

 14: }

defaultCommands is static due to the expense of parsing the xml file and loading it into the API. On one hand, this isn’t completely evil because the defaultCommands is private. When you use the default constructor, it defaults to using the static commands. If you use the other constructor (not shown), you can pass in your own. But, if you never use the default constructor, then that static object was loaded for no reason, which is evil.

I just don’t like statics for this type of thing at all. Whenever I have instance code and static code mixed, I feel unclean. I always want a layer in between, or an IOC.

So how would IOC help in this case? It fixes everything!

Here’s the other constructor:

 1: public CommandService(Commands commands)

 2: {

 3:     this.commands = commands;

 4: }

We simply register a factory for the COMMANDS object in the container, and set it’s lifetime to SINGLETON. Now:

  • The container will create the commands object when it’s needed (so it’s never created unnecessarily)
  • The commands object doesn’t need to be static, because as a singleton the container will keep an instance alive
  • The container will pass the commands instance to the constructor automatically

So everything’s much neater. But, the setup is more complicated. You have to register all of the types. And that’s where some start to lose interest. The container configuration can quickly become unwieldy. People who don’t appreciate the benefit IOC can quickly become flustered by it. You can be simple and inflexible, or more complicated and completely flexible. (That said, there are ways to mitigate the complexity. Two that I often fall back on are: 1) let the container do most of the work. You don’t have to register every type and every constructor parameter. Unity does a lot without you having to be explicit. You can often delete a bunch of configuration and still be ok. 2) Provide default wiring. You’re objects don’t have to require that everything is injected, it just has to be able to support it for when it’s needed. If you know an object is usually going to be wired up a particular way, then have the default constructor do the wiring automatically (assuming no static resources). Or, provide a static create method that does the default wiring for you.)

All of the above applies to Wcf services as well. Wcf simply instantiates an instance of the service type. If that type has dependencies that you want to inject, then without something like this solution, your instance would have to rely on static factories, or a static IOC container (very bad) to get what it needs.

Now we’re back to where we started: integrate Wcf and Unity.

There are several pieces to get this going. It’s shown below going from the Global.asax and through the Wcf pipeline. To implement it, though, you’ll have to work backwards.

Global.asax, RegisterRoutes()

The RegisterRoutes() method is standard in the Mvc3 Global.asax. I’m registering a route to a service with the name of Configuration.svc. The routing engine prevents the need for an actual svc file. However, to drop the .SVC part, changes are needed in IIS configuration, so I left the SVC. We instruct the routes api to use the UnityWebServiceHostFactory to create the service host. We pass it our Unity container.

 1: // load the container

 2: var container = new UnityContainer();

 3: var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

 4: section.Configure(container, "WebSite");

 5:

 6:

 7: // service registrations

 8: // rest

 9: routes.Add(new ServiceRoute("Configuration.svc", new UnityWebServiceHostFactory(container), typeof(ConfigurationService)));

UnityWebServiceHostFactory

This is the class that instantiates the service host. The service host we’re instantiating is a new class that extends WebServiceHost.

 1: namespace SomeGuySoftware.DevDash.Mvc.Unity

 2: {

 3:     using System;

 4:     using System.ServiceModel;

 5:     using System.ServiceModel.Activation;

 6:     using Microsoft.Practices.Unity;

 7:

 8:     public class UnityWebServiceHostFactory : WebServiceHostFactory

 9:     {

 10:         private readonly IUnityContainer container;

 11:         public UnityWebServiceHostFactory(IUnityContainer unity)

 12:         {

 13:             if (unity == null)

 14:             {

 15:                 throw new ArgumentNullException("unity");

 16:             }

 17:

 18:             this.container = unity;

 19:         }

 20:

 21:         protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)

 22:         {

 23:             return new UnityWebServiceHost(this.container, serviceType, baseAddresses);

 24:         }

 25:     }

 26: }

UnityWebServiceHost

This is the service host. It is a subclass of WebServiceHost, which provides restful services. We override the OnOpening method and insert a behavior.

You can add the behavior many different ways, but this one is nice because you wrap it all up in the service host. The host also hangs on the the container, which we will use later in the instance provider.

Strictly speaking, you don’t need to create this service host subclass. You could instead always add the behavior manually either through code or through attributes. But, this is better.

 1: namespace SomeGuySoftware.DevDash.Mvc.Unity

 2: {

 3:     using System;

 4:     using System.ServiceModel.Web;

 5:     using Microsoft.Practices.Unity;

 6:

 7:     /// <summary>

 8:     /// A WebServiceHost with a unity container.

 9:     /// The unity container is used to create the service instances.

 10:     /// </summary>

 11:     public class UnityWebServiceHost : WebServiceHost

 12:     {

 13:         /// <summary>

 14:         /// Initializes a new instance of the UnityWebServiceHost class.

 15:         /// </summary>

 16:         /// <param name="container">Required. The unity container that provides the service instances.</param>

 17:         /// <param name="serviceType">Required. The type of the service.</param>

 18:         /// <param name="baseAddresses">The service's base addresses.</param>

 19:         public UnityWebServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)

 20:             : base(serviceType, baseAddresses)

 21:         {

 22:             if (container == null)

 23:             {

 24:                 throw new ArgumentNullException("container");

 25:             }

 26:

 27:             this.Unity = container;

 28:         }

 29:

 30:         /// <summary>

 31:         /// Gets the unity container that's responsible for the service host's intance management.

 32:         /// </summary>

 33:         public IUnityContainer Unity

 34:         {

 35:             get;

 36:             private set;

 37:         }

 38:

 39:         protected override void OnOpening()

 40:         {

 41:             base.OnOpening();

 42:             this.Description.Behaviors.Add(new UnityInstanceProviderBehavior());

 43:         }

 44:     }

 45: }

UnityInstanceProviderBehavior

The behavior iterates all of the endpoint dispatchers and assigns a new instance provider. Now, whenever Wcf needs to create a service instance, it’s going to call our class instead of it’s own.

 1: namespace SomeGuySoftware.DevDash.Mvc.Unity

 2: {

 3:     using System.Linq;

 4:     using System.ServiceModel;

 5:     using System.ServiceModel.Description;

 6:     using System.ServiceModel.Dispatcher;

 7:

 8:     public class UnityInstanceProviderBehavior : IServiceBehavior

 9:     {

 10:         public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

 11:         {

 12:             foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>())

 13:             {

 14:                 foreach (EndpointDispatcher ed in dispatcher.Endpoints)

 15:                 {

 16:                     ed.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(serviceDescription.ServiceType);

 17:                 }

 18:             }

 19:         }

 20:

 21:         #region Not Used

 22:         public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

 23:         {

 24:         }

 25:

 26:         public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)

 27:         {

 28:         }

 29:         #endregion

 30:     }

 31: }

UnityInstanceProvider

At long last, we get to use the unity container. Recall that the unity container was passed into the service host. The instance provider will work its way back to the service host to get the container and use it to provide the service class.

GetInstance and ReleaseInstance both use a GetUnityContainer() extension method. I added the extension method just because it’s more easily readable than casting inline.

 1: namespace SomeGuySoftware.DevDash.Mvc.Unity

 2: {

 3:     using System;

 4:     using System.ServiceModel;

 5:     using System.ServiceModel.Channels;

 6:     using System.ServiceModel.Dispatcher;

 7:

 8:     public class UnityInstanceProvider : IInstanceProvider

 9:     {

 10:         private readonly Type type;

 11:         public UnityInstanceProvider(Type type)

 12:         {

 13:             this.type = type;

 14:         }

 15:

 16:         public object GetInstance(InstanceContext instanceContext)

 17:         {

 18:             return this.GetInstance(instanceContext, null);

 19:         }

 20:

 21:         public object GetInstance(InstanceContext instanceContext, Message message)

 22:         {

 23:             return instanceContext.GetUnityContainer().Resolve(this.type, null);

 24:         }

 25:

 26:         public void ReleaseInstance(InstanceContext instanceContext, object instance)

 27:         {

 28:             instanceContext.GetUnityContainer().Teardown(instance);

 29:         }

 30:     }

 31: }

Extension Method

This is the extension method that digs the instance context out of the service host.

Earlier, I mentioned that you don’t need to create a service host subclass. If you didn’t, then you wouldn’t be able to retrieve the container this way. But, you could instead drill into host.description.behaviors, and pull it off the UnityInstanceProviderBehavior. (You should definitely use the service host subclass, though. This is just completing an earlier thought.)

 1: namespace SomeGuySoftware.DevDash.Mvc.Unity

 2: {

 3:     using Microsoft.Practices.Unity;

 4:     using System.ServiceModel;

 5:

 6:     public static class ExtensionMethods

 7:     {

 8:         public static IUnityContainer GetUnityContainer(this InstanceContext instanceContext)

 9:         {

 10:             return ((UnityWebServiceHost)instanceContext.Host).Unity;

 11:         }

 12:     }

 13: }

And there you go.

But wait, There’s More!

Update: 7/12/2011

I started swapping over my services to use it and ran into a glitch.

Typically when dealing with Wcf services, the abstraction you want to deal with is the service contract, which is an interface.

I wanted to register the service like this:

 1: routes.Add(new ServiceRoute("Configuration.svc", new UnityWebServiceHostFactory(container), typeof(IConfigurationService)));

The problem arises when the UnityWebServiceHost passes IConfigurationService up to the base. It can’t do it; the WebServiceHost only accepts service types, which is an actual type, not an interface. Somehow, we need to pass it a type that is either the service contract interface (ideal), or something compatible with our actual implementation (ie: a base class.)

There are least two solutions to this problem.

Change the Constructor – I don’t like this one

We can change the constructor on UnityWebServiceHost to resolve the service type, and then get a type.

 1: public UnityWebServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)

 2:     : base(container.Resolve(serviceType, null).GetType())

 3: {

 4:    this.Unity = container;

 5: }

I don’t like it for a couple of reasons:

  • You resolve the instance just to call GetType() on it. You don’t need the resolved object, just it’s type. It’d be handy if Unity provided a type lookup in addition to the resolve.
  • You can’t validate the container before using it.

Register a Base Class Instead

This is the one I’m going with. It’s not great, but it’s better than the previous option. Instead of registering the interface type, register an abstract class that implements the interface, then assign it to an implementation of the subclass.

My interface is IConfigurationService. I have an abstract class named ConfigurationService that implements the interface. Then, ConfigurationServiceXml is a subclass of Configuration service.

 1: routes.Add(new ServiceRoute("Configuration.svc", new UnityWebServiceHostFactory(container), typeof(ConfigurationService)));

 2:

 3: namespace SomeGuySoftware.DevDash.Contracts

 4: {

 5:     using System.Collections.Generic;

 6:     using System.ServiceModel;

 7:     using System.ServiceModel.Web;

 8:

 9:     [ServiceContract]

 10:     public interface IConfigurationService

 11:     {

 12:         [OperationContract]

 13:         [WebGet(UriTemplate="Environments?getServers={getServers}&getFeatureGroups={getFeatureGroups}")]

 14:         IEnumerable<DevEnvironment> GetAllEnvironments(bool getServers, bool getFeatureGroups);

 15:

 16:         [OperationContract]

 17:         [WebGet(UriTemplate="Environment/{environmentName}?getServers={getServers}&getFeatureGroups={getFeatureGroups}")]

 18:         DevEnvironment GetEnvironment(string environmentName, bool getServers, bool getFeatureGroups);

 19:

 20:         [OperationContract]

 21:         [WebGet(UriTemplate="Server/{ServerName}?getFeatureGroups={getFeatureGroups}")]

 22:         Server GetServer(string serverName, bool getFeatureGroups);

 23:

 24:         [OperationContract]

 25:         [WebGet(UriTemplate = "FeaturePage/?serverTypeName={serverTypeName}&serverName={serverName}&featureGroupName={featureGroupName}&pageName={pageName}")]

 26:         FeaturePage GetFeaturePage(string serverTypeName, string serverName, string featureGroupName, string pageName);

 27:     }

 28: }

 29:

 30: namespace SomeGuySoftware.DevDash.Contracts

 31: {

 32:     using System.Collections.Generic;

 33:     using System.ServiceModel.Activation;

 34:

 35:     [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

 36:     public abstract class ConfigurationService : IConfigurationService

 37:     {

 38:         public abstract IEnumerable<DevEnvironment> GetAllEnvironments(bool getServers, bool getFeatureGroups);

 39:         public abstract DevEnvironment GetEnvironment(string environmentName, bool getServers, bool getFeatureGroups);

 40:         public abstract Server GetServer(string serverName, bool getFeatureGroups);

 41:         public abstract FeaturePage GetFeaturePage(string serverTypeName, string serverName, string featureGroupName, string pageName);

 42:     }

 43: }

Now, you can swap out the service via configuration only; no need to change the global.asax when you write a new implementation of the service.

I put the abstract class in the CONTRACTS assembly next to the service contract. It doesn’t provide any implementation, so nothing is revealed. Anyone write a new implementation would have the contracts assembly already (that’s where the service contract is).

This extra step isn’t great. Does anyone have a better idea?

Advertisements

3 Responses to Wcf and Unity Revisited

  1. the following code:
    var section = (UnityConfigurationSection)ConfigurationManager.GetSection(“unity”);
    gives this error:
    Unable to cast object of type ‘System.Configuration.DefaultSection’ to type ‘Microsoft.Practices.Unity.Configuration.UnityConfigurationSection’.

    can u help?

    • hamletcode says:

      Hello

      Sure, I can help. That code works with Unity version 2. If you want, send me your application configuration file and the code that’s trying to load it.

      The post assumes familiarity with Unity. If you’re not familiar, then you might be missing some stuff. You have to register the unity conifguration section in the app.config.

      IE:

      Then register your types by adding a unity element.

      An example:

      <type
      type="SomeGuySoftware.DevDash.Contracts.ConfigurationService, SomeGuySoftware.DevDash.Contracts"

      My container name is WebSite, but that's optional. If you only have one container, you don't have to give it a name.

      Feel free to contact me with any questions. Jay@allardworks.com

  2. hamletcode says:

    I’ve changed 2 key things since writing this:
    – I now base it on IServiceLocator rather than IUnityContainer so that you can use a variety of IOCs. I only use unity and don’t expect to change that, but it’s a trivial task to use IServiceLocator, so might as well.
    – My 7/12/2011 update is no longer in place. I am no longer hosting the services in IIS. When I rewrote it, I no longer needed the extra layer. I don’t know if it’s because I did it better this time, or if something in IIS/mvc is what required me to do it as I did back then. Now, it’s just plain old services. The service host needs the type initially to construct the service, but after that the instance manager handles it. (The service type needs a default constructor, though.)

Leave a Reply

Please log in using one of these methods to post your comment:

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: