Adding Extension Methods to 2.0

July 19, 2011

Today, I was compiling a solution and attempting to get rid of all compiler warnings. There was one that I couldn’t get rid of.

Warning 1 The predefined type ‘System.Runtime.CompilerServices.ExtensionAttribute’ is defined in multiple assemblies in the global alias; using definition from ‘c:\temp\ConsoleApplication2\Program.cs’ ConsoleApplication2

That one is from the sample code (below). The actual one was produced by Gallio.

Extension methods were introduced in .NET 3.0. .NET 3 and 3.5 use the .NET 2 Runtime; they just add a ton of stuff to do it.

If you have 3.0 installed, but your project targets 2.0, you can still use extension methods by adding this code somewhere in your project:

   1: namespace System.Runtime.CompilerServices

   2: {

   3:     public class ExtensionAttribute : Attribute

   4:     {

   5:     }

   6: }

It creates an attribute that is part of the underlying magic that makes extension methods work. It doesn’t exist in 2.0 until you add it yourself. The compiler will find the attribute (not caring that it came from you), and will implement aforementioned magic. Sneaky.

To see this action:

  1. Create a new console project
  2. Change it to target .net 2.0
  3. Paste the following code
   1: namespace ConsoleApplication2

   2: {

   3:     class Program

   4:     {

   5:         static void Main(string[] args)

   6:         {

   7:         }

   8:     }

   9:  

  10:     public class IceCream

  11:     {

  12:     }

  13:  

  14:     public static class ExtensionMethods

  15:     {

  16:         public static void Melt(this IceCream iceCream)

  17:         {        

  18:         }

  19:     }

  20: }

 

Now Compile.

You will get this error:

Error 1 Cannot define a new extension method because the compiler required type ‘System.Runtime.CompilerServices.ExtensionAttribute’ cannot be found. Are you missing a reference to System.Core.dll? c:\temp\ConsoleApplication2\Program.cs 16 33 ConsoleApplication2

Now, add to the code the ExtensionAttribute shown earlier in this post, and compile again. This time, it compiles. You now have extension methods in a 2.0 project. Why? Because 3.0 added the ability to the 2.0 compiler, and you exposed the ability by providing the essential attribute.

Here comes the itsy bitsy problem. Change the project to 4.0 and compile. It will compile, but you get this warning:

Warning 1 The predefined type ‘System.Runtime.CompilerServices.ExtensionAttribute’ is defined in multiple assemblies in the global alias; using definition from ‘c:\temp\ConsoleApplication2\Program.cs’ ConsoleApplication2

The problem is that you have declared the extension attribute yourself, and it also exists in mscore. So, there are two of the same attributes, and it doesn’t know which to use. I don’t know how it makes the decision on which to use, but in this case it chose mine. Mine must be cooler. I knew there was something special about it when I typed it.

Gallio

Now that we’re through all that: my specific problem earlier is that my project had a reference to GALLIO.DLL. Gallio.dll must define the attribute to make extension methods available for itself in 2.0. So, I can’t get rid of the warning without dropping the Gallio.

Or, perhaps there’s a newer version of Gallio that doesn’t add this attribute automatically. I haven’t looked into it.


Wcf and Unity Revisited

July 12, 2011

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?