Factory Pattern
Introduction
In the previous post I described using the Repository pattern to encapsulate set of Entities. The next step is creation an class which will be responsible for creating those repositories. It will be an implementation of Factory pattern ( simplified version of Factory Method pattern).
Problem definition
The Factory Design Pattern is probably the most used design pattern in modern programming languages like Java and C#. Its aim is to create objects without exposing the instantiation logic to the client. It also refers to the newly created object through a common interface. Another important factor is fact that we usually implement Factories using also Singleton pattern.
A singleton is a class which only allows a single instance of itself to be created, and usually gives simple access to that instance. In this post I’ll present also thread-safe implementation of this pattern.
Solution
Let me remind a generic implementation of Repository pattern which I presented in the previous post.
interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
IEnumerable<T> GetByQuery(Expression<Func<T, bool>> where);
T GetByID(int ID)
void Delete(T entity);
void Add(T entity);
}
The factory we want to create has to fulfil several requierments:
- It must contain generic function creating repositories
- The repositories has to be refereed through IRepository<T> interface
- It must be singleton
- It must be thread-safe
First of all I’ll implement the Factory satisfying two first conditions – simple class with one function for creating Repositories.
public class RepositoryFactory
{
public IRepository<T> GetRepositoryInstance<T, TRepository>()
where TRepository : IRepository<T>, new() where T : System.Data.Objects.DataClasses.EntityObject
{
return new TRepository();
}
}
As You can see it is rather simple. The function creating classes is an generic function which takes two types – the first one is a type of Entity which repository we are going to create, and the second one is a type of Repository we are going to create. As You can see, despite the fact that we create objects of concrete repository the function is returning IRepository<T>. This implementation is rather simple but contains one big drawback – someone can create many objects of Factory class what is absolutely not necessary. So let’s make our Factory a singleton.
public sealed class RepositoryFactory
{
private static RepositoryFactory _instance;
public static RepositoryFactory Instance
{
get { return _instance ?? (_instance = new RepositoryFactory()); }
}
private RepositoryFactory()
{
}
public IRepository<T> GetRepositoryInstance<T, TRepository>()
where TRepository : IRepository<T>, new() where T : System.Data.Objects.DataClasses.EntityObject
{
return new TRepository();
}
}
The above solution presents one of the most popular Singleton Design Pattern implementation. The constructor of class is private so we cannot just create an Factory object. The access to object is get by an Instance property ( which, BTW, contain also so Lazy Loading features – the object is created only when it is need, not during program start ) which can return only existing object of this class. Only this instance is able to invoke a function which creates repositories.
As hinted at before, the above is not thread-safe. Two different threads could both have evaluated the test if (instance==null) and found it to be true, then both create instances, which violates the singleton pattern. Note that in fact the instance may already have been created before the expression is evaluated, but the memory model doesn’t guarantee that the new value of instance will be seen by other threads unless suitablememory barriers have been passed. Below solution presents simple thread-safe mechanism base on lock keyword.
public sealed class RepositoryFactory
{
private static RepositoryFactory _instance;
private static readonly object _padlock = new object();
public static RepositoryFactory Instance
{
get
{
lock (_padlock)
{
return _instance ?? (_instance = new RepositoryFactory());
}
}
}
private RepositoryFactory()
{
}
public IRepository<T> GetRepositoryInstance<T, TRepository>()
where TRepository : IRepository<T>, new() where T : System.Data.Objects.DataClasses.EntityObject
{
return new TRepository();
}
}
Conclusion.
This post presents usage an implementation of next, two popular Design Patterns – the Factory Pattern used for creation of objects from same family ( e.g. implementing same Interface) and Singleton Pattern which ensures that there will be only one object of given class in a application -the presented solution is also thread-safe what is very important in case of growing popularity of parallel programming methods.
Posted on 4 September 2011, in .NET Developing, Design Patterns and tagged .NET Framework, C#, data access, Design Patterns, Factory, Singleton. Bookmark the permalink. Leave a Comment.
Leave a Comment
Comments (0)