ASP.NET Web Services Dependency Injection using Unity

Recently, I had to setup Unity IoC container in an existing ASP.NET 3.5 Web Forms application. This application had not only web pages (.aspx files), but also some Web Services (.asmx files). After some research, I found out David Hayden’s screencast: Unity IoC and ASP.NET screencast – Dependency Injection into Web Pages.

You can use a similar technique for your Web Services – that’s what I’ll show you in this article.

Table of contents

Example – Adding logging to your application

You have the following interface and its implementation:

public interface ILogger
{
    void Write(string message);
}

public class DebugLogger : ILogger
{
    public void Write(string message)
    {
        Debug.WriteLine(message);
    }
}

 

Step 1: Setting up the container in Global.asax

The first step is to setup Unity Container in Global.asax file. This is a good place to do it because it can be accessed either by web pages or by web services.
The CreateContainer() method is the place where the dependencies are specified.

public class Global : HttpApplication, IContainerAccessor
{
    private static IUnityContainer _container;

    public static IUnityContainer Container
    {
        get
        {
            return _container;
        }
        private set
        {
            _container = value;
        }
    }

    IUnityContainer IContainerAccessor.Container
    {
        get
        {
            return Container;
        }
    }

    protected void Application_Start(object sender, EventArgs e)
    {
        CreateContainer();
    }

    protected virtual void CreateContainer()
    {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<ILogger, DebugLogger>();
        
        Container = container;
    }
}

 

Step 2: Creating a base class for the services

Create a generic BaseService that all your services will inherit from. The dependencies will be injected when you create an instance of the service (default constructor).

public abstract class BaseService<T> : System.Web.Services.WebService where T : class
{
    public BaseService()
    {
        InjectDependencies();
    }

    protected virtual void InjectDependencies()
    {
        HttpContext context = HttpContext.Current;

        if (context == null)
            return;

        IContainerAccessor accessor = context.ApplicationInstance as IContainerAccessor;

        if (accessor == null)
            return;

        IUnityContainer container = accessor.Container;

        if (container == null)
            throw new InvalidOperationException("Container on Global Application Class is Null. Cannot perform BuildUp.");

        container.BuildUp(this as T);
    }
}

 

Step 3: Setting up the services

Now all you need to do is to inherit from the BaseService and invoke its base constructor.
Don’t forget to add the [Dependency] attribute to your dependency, and it has to be public.

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class DummyService : BaseService<DummyService>
{
    [Dependency]
    public ILogger Logger
    {
        get;
        set;
    }

    public DummyService() : base()
    {
    }

    [WebMethod]
    public string HelloWorld(string name)
    {
        string message = string.Format("Hello World, {0}!", name);

        this.Logger.Write(message);

        return message;
    }
}

That’s it! Now you just need to compile and run the application and see it in action šŸ™‚

Feel free to download the demo application

References

Downloads

Download the demo project (VS2010): UnityAsmxWebServices.zip

Advertisements

Entity Framework and T4: Generating GetHashCode() for your entities

A simple Entity Framework T4 template that generates GetHashCode() method

Table of contents

GetHashCode() overview

A hash code is a numeric value that is used to identify an object during equality testing, and it can also serve as an index for an object in a collection, such as a List, Dictionary or HashTable.

The problem is that the default .NET implementation of GetHashCode() does not guarantee unique values for different values, so you should override this method and provide your own implementation.

Some rules for implementing GetHashCode() are:

  • If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values.
  • The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state
  • For the best performance, a hash function must generate a random distribution for all input
  • Implementations of the GetHashCode method must not result in circular references (it can lead to a StackOverflowException).
  • Implementations of the GetHashCode method must not throw exceptions.

This is a short overview of GetHashCode() method, taken from MSDN. You can read more here: Object.GetHashCode Method

Implementing GetHashCode()

I found a great post on StackOverflow on this topic. Jon Skeet has provided a good and simple implementation. Basically, you need to use prime numbers like 17, 23, 29, 31 in the hash code calculation. I decided to include also the type of the object in the calculation, because two objects with identical properties/values can return the same hash code.

public class Organisation
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Country { get; set; }

	public override int GetHashCode()
	{
		unchecked
		{
			int multiplier = 31;
			int hash = GetType().GetHashCode();

			hash = hash * multiplier + Id.GetHashCode();
			hash = hash * multiplier + (Name == null ? 0 : Name.GetHashCode());
			hash = hash * multiplier + (Country == null ? 0 : Country.GetHashCode());

			return hash;
		}
	}
}

Using T4 templates to generate GetHashCode()

T4 is a code generator built right into Visual Studio. You can generate any text file using T4 templates: C#, javascript, HTML, XML and many others. If you’ve never heard about it, this is a good place to start:

T4 (Text Template Transformation Toolkit) Code Generation – Best Kept Visual Studio Secret

I’ve modified the ADO.NET C# POCO Entity Generator template to generate GetHashCode() method for each entity in the model. Feel free to download the demo project (VS2010).

References

Downloads

Download the demo project (VS2010): T4-GetHashCode.rar

Technorati Tags: , , , ,