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!