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.
A couple years ago, when working on a service bus, I did a blog post on integrating unity and Wcf:
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.
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:
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:
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.
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.
This is the class that instantiates the service host. The service host we’re instantiating is a new class that extends WebServiceHost.
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.
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.
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.
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.)
And there you go.
But wait, There’s More!
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:
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.
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.
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?