I have an MVC app using a 3-tier pattern: DAL <-> Service <-> UI and I'm trying to add AutoFac for testing my MVC controllers as well as services.
A couple questions:
1) How do I use AutoFac to tell my service layer to use a specific context?
Currently I'm using builder.Register(c => c.Resolve<IRepo>()).As<Repo>();
but this exposes IRepo to the UI, which would allow them to bypass service layer validation and business rules.
2) The Repo and MockRepo are identical besides the constructor identifying which context to use. It's there because the UI doesn't have a reference to DAL and so I can't pass in an IDataContext. Is there a way to remove the redundant code/classes and still be able to use DI?
/* DAL */
public interface IDataContext
{
T GetById<T>(int Id);
}
// Entity Framework context
public class EFContext : DbContext, IDataContext
{
public EFContext() : base("MyConnectionString")
{...}
public T GetById<T>(int Id)
{...}
}
// In-memory context for testing
public class MockContext : IDataContext
{
public MockContext()
{...}
public T GetById<T>(int Id)
{...}
}
/* Service */
public interface IRepo
{
T GetById<T>(int id);
}
// Entity Framework Repo
public class Repo
{
private IRepo _repo;
public Repo()
{
_repo = new EFContext();
}
public T GetById<T>(int Id)
{
return _repo.GetById<T>(Id);
}
}
// In-memory Repo
public class MockRepo : RepoBase
{
private IRepo _repo;
public MockRepo()
{
_repo = new MockContext();
}
public T GetById<T>(int Id)
{
return _repo.GetById<T>(Id);
}
}
// Service to be used in the UI
public class StudentService
{
public StudentService(IRepo repo)
{
_repo = repo;
}
public void ExpelStudent(int studentId)
{
var student = _repo.GetById(studentId);
...
_repo.Save();
}
}