web 2.0

Dealing With Enterprise Library Injection Policy And Unity IoC

Hi,

In this article I’ll provide a Generic Unity Factory Class in order to take advantage of Unity and Injection Policy easily.

For Example purpose I created a simple Web Application Project and referenced the following assemblies

  • Microsoft.Practices.EnterpriseLibrary.Common
  • Microsoft.Practices.EnterpriseLibrary.PolicyInjection
  • Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers
  • Microsoft.Practices.EnterpriseLibrary.ObjectBuilder2

The goal of this article is to use Unity as an IoC Container and Use Policy Injection provided by Enterprise Library Policy Injection Application Block to handle CachingCallHandler on our Data Access Class Methods.

Firstly assuming a Book Model Class.

public class Book
{
    public Int32 BookId { get; set; }
    public String Title { get; set; }
}

Then the BookDAO

public interface IBookDAO
{
    List<Book> GetBooks();
}
public class BookDAO : IBookDAO
{
    [CachingCallHandler(0, 0, 10)]
    public List<Book> GetBooks()
    {
        HttpContext.Current.Trace.Warn("Called GetBooks from BookDAO.");
        return new List<Book>();
    }
}

For this Example purpose I defined the CachingCallHandler from InjectionPolicy Call Handlers to Expire every 10 seconds and the GetBooks method only Show a Trace Message when Method will be called then returns an empty List of Book.

Now in my Default.aspx Page I enabled Tracing in order to display BookDAO Message.

<%@ Page Language="C#" AutoEventWireup="true" Trace="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication9._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    </div>
    </form>
</body>
</html>

So we got our Basic Web Application.

Now talk about Unity and the UnityFactory Class :)

The UnityFactory Class use the Singleton Pattern since we only need a single instance of it.

public class UnityFactory<T> where T : class
{
    private static readonly UnityFactory<T> instance = new UnityFactory<T>();
    private static readonly IUnityContainer container = null;
    private static readonly List<Object> instances = new List<Object>();

    static UnityFactory()
    {
        var Config = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
        if (Config != null && Config.Containers.Default != null)
        {
            Config.Containers.Default.Configure(container);
        }
        else
        {
            container = new UnityContainer();
        }
    }

    UnityFactory()
    {
    }

    public static T GetObject()
    {
        T o = default(T);

        var q = instances.Where(p => p is T);
        if (q.Count() > 0)
        {
            o = q.FirstOrDefault() as T;
        }
        else
        {
            o = container.Resolve<T>();
            if (o != null) instances.Add(o);
        }
        if (o != null)
            o = PolicyInjection.Wrap<T>(o);
        return o;
    }
    public static void Register<TConcret>()
    {
        if (container != null)
        {
            container.RegisterType(typeof(T), typeof(TConcret));
        }
    }
}

Note the GetObject Method : This will firstly check in the Instance Collection if there is an Instance of the Asked Object, if yes return it.

Otherwise it will try to Resolve it according to the Unity Configuration in Web.config. If there is no configuration in Web.config it will Resolve the Object according to the RegisteredTypes in the Container.

So in our Web Application we need to Add a Global.asax file in order to register the mapping between the interface IBookDAO and the concret class BookDAO.

protected void Application_Start(object sender, EventArgs e)
{
    // Register Mapping Between IBookDAO and the Concret Class BookDAO in Unity Container
    UnityFactory<IBookDAO>.Register<BookDAO>();
}

Now we can use the UnityFactory to Inject Dependency of the IBookDao Interface in the Default.aspx Code-Behind.

public partial class _Default : System.Web.UI.Page
{
    protected override void OnLoad(EventArgs e)
    {
        IBookDAO dao = UnityFactory<IBookDAO>.GetObject();
        List<Book> books = dao.GetBooks();
        base.OnLoad(e);
    }
}

Really simple isn’t it ? :)

Now take a look at the ASP.NET Trace results

image

On first Page Call, we got the Trace Message from the BookDAO : “Called GetBooks from BookDAO.”

The BookDAO.GetBooks() was Called and Cached.

Now Refresh the Page.

image

Data are Cached ! There is no Trace Message from BookDAO anymore. If you wait a few second and refresh again the page, the message will reappear since the Cache Expired.

 

Conclusion : Enterprise Library Policy Injection is a pretty good way in order to simply Manage Cache Policies and moreover taking Advantage of Unity IoC for Dependencies Injection.

 

Hope this help’s!

More Informations :

http://www.codeplex.com/entlib

http://www.codeplex.com/unity



Views(2136)

kick it on DotNetKicks.com

Share/Save/Bookmark Subscribe

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

ASP.NET | C#

Comments

Technorati Profile