Entity Framework usando un patrón de repositorio, unidad de trabajo y unidad

Usando una combinación proporcionada poreste ejemplo yesta implementación Estoy tratando de crear una solución que separa laUnitOfWork clase de los repositorios individuales, ya que violan el principio abierto-cerrado, ya que cada vez que agregue un nuevo repositorio, tendrá que modificar elUnitOfWork clase. Estoy usando Unity como el contenedor de IoC para conectar las dependencias.

El problema que tengo es que al cablear automáticamente elUnitOfWork, IDbContext y los repositorios (IEmployeeRepository yICustomerRepository) utilizando Unity, los repositorios se inyectarán con instancias separadas deUnitOfWork, que, por supuesto, derrota al propósito. Necesito compartir el contexto a través de los repositorios, y parece que me falta una pieza para este rompecabezas: en este momento (ver Capa de servicio) laUnitOfWork será una instancia diferente de laUnitOfWork Para cada uno de los repositorios.

¿Cómo inyectar elIUnitOfWork en la capa de servicio y pasar esto instanciadocompartido UnitOfWork ¿Clase a los repositorios respectivos, usando la unidad y la inyección de dependencia?

Aquí está mi solución propuesta (fabricada):

Repositorios

public interface IRepository<TEntity> where TEntity : class
{
    TEntity Create();
    // omitted for brevity
}

public class Repository<TEntity> : IRepository<TEntity>
    where TEntity : class
{       
    private readonly DbContext _context;

    public Repository(IUnitOfWork uow)
    {
        _context = uow.Context;
    }

    public virtual TEntity Create(TEntity entity)
    {
        return _context.Set<TEntity>().Add(entity);         
    }   

    // omitted for brevity      
}

public interface IEmployeeRepository : IRepository<Employee>
{
}

public interface ICustomerRepository : IRepository<Customer>
{
}

public class EmployeeRepository : Repository<Employee>
{
    public EmployeeRepository(IUnitOfWork uow)
        : base(uow)
    {
    }
}

public class CustomerRepository : Repository<Customer>
{
    public CustomerRepository(IUnitOfWork uow)
        : base(uow)
    {
    }
}

DbContext Factory

public interface IDbContextFactory
{
    DbContext GetContext();
}

public class DbContextFactory : IDbContextFactory
{
    private readonly DbContext _context;

    public DbContextFactory()
    {
        _context = new MyDbContext("ConnectionStringName");
    }

    public DbContext GetContext()
    {
        return _context;
    }
}

Unidad de trabajo

public interface IUnitOfWork
{
    void SaveChanges();
    DbContext Context { get; }
}

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private readonly DbContext _context;
    private bool disposed = false;

    public UnitOfWork(IDbContextFactory contextFactory)
    {
        _context = contextFactory.GetContext();
    }

    public void SaveChanges()
    {
        if (_context != null)
        {
            _context.SaveChanges();
        }
    }

    public DbContext Context
    {
        get { return _context; }
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

Servicio

public class CompanyService
{
    private readonly IUnitOfWork _uow;
    private readonly IEmployeeRepository _employeeRepository;
    private readonly ICustomerRepository _customerRepository;

    public CompanyService(IUnitOfWork uow, IEmployeeRepository employeeRepository, ICustomerRepository customerRepository)
    {           
        _uow = uow;
        _employeeRepository = employeeRepository;
        _customerRepository = customerRepository;
    }

    // over-simplified example method
    public void AddEmployeeAndCustomer()
    {
        _employeeRepository.Create(new Employee {Id = 1, Name = "Test Employee"});
        _customerRepository.Create(new Customer { Id = 2, Name = "Test Customer" });

        _uow.SaveChanges();
    }

}

Respuestas a la pregunta(1)

Su respuesta a la pregunta