lunes, 28 de diciembre de 2009

Inyectando DataContext en repositorios

Hoy tuve que hacer un refactor de una aplicación para inyectar DataContext en los repositorios por IoC y utilizar el patrón unit of work.

Esta es la interface de un repositorio:

public interface IContactInformationRepository
{
void Save(ContactInformation contactInformation);
}

y su implementación (recibe por constructor el DataContext):

public class ContactInformationRepository : IContactInformationRepository
{
private readonly DataContext dataContext;
public ContactInformationRepository(DataContext dataContext)
{
this.dataContext = dataContext;
}

public void Save(ContactInformation contactInformation)
{
dataContext.ContactInformations.InsertOnSubmit(contactInformation);
}
}

Para inyectar el data context por IoC, usando StructureMap:

ForRequestedType()
.CacheBy(InstanceScope.HttpContext)
.TheDefault.Is.ConstructedBy(() =>
new DataContext(ConfigurationManager.AppSettings["connectionString"]));

Si bien debería haber usado una interface IDataContext (programar hacia interfaces, no implementaciones), elegí el camino más fácil, ya que en este caso no necesito cambiar la implementación del DataContext.

Luego para implementar el patrón unit of work, me basé en este post:
http://weblogs.asp.net/rashid/archive/2009/02/26/implementing-unitofwork-pattern-in-linq-to-sql-application.aspx

Los repositorios no hacen el commit de la unit of work. La service layer tiene la responsabilidad de hacerlo. Para eso, cada servicio que realiza cambios en la base de datos tiene una dependencia a la IUnitOfWork. El IoC es responsable que configurar correctamente los repositorios, servicios y unit of work para que todos vean la misma instancia de DataContext:
http://codepaste.net/zz6g2s

Este es un unit test del servicio, que prubeba la unit of work usando Moq:
http://codepaste.net/hro3ob

En este caso, el servicio usa directamente el repositorio (y no un objeto mock) ya que no se impacta en base de datos, dado que la unit of work es un objeto mock.

saludos!

No hay comentarios.: