patterncsharpMinor
EF code-first solution architecture, which exposes freely the data repo to the UI controllers
Viewed 0 times
architecturetheexposeswhichfreelycontrollersfirstcodesolutiondata
Problem
I have a project template and like to usually work with the following setup (grossly simplified, but that's the gist of it).
CompanyName.ProjectName.Business.Entities
I define my business objects. I am not going after DDD, so having
The following is an over-simplified example of such object, with the only business logic in it - "description is required".
CompanyName.ProjectName.Business.Interface.DataRepository
Although my solution is tightly coupled with Entity Framework and I don't make an effort to abstract this (it is pointless), I don't want anything working directly with
In CompanyName.ProjectName.Infrastructure.EfRepository
CompanyName.ProjectName.UI.MVC
What I like most about this architecture is that I can just do this:
```
public class HomeController : Controller
{
private DataRepositoryFactory dataRepositoryFactory;
CompanyName.ProjectName.Business.Entities
I define my business objects. I am not going after DDD, so having
[Key] is definitely not an issue for me. Nevertheless, the classes are true business objects and they have as much business logic rules in them as necessary.The following is an over-simplified example of such object, with the only business logic in it - "description is required".
public class BugReport
{
[Key]
public int ID { get; private set;}
public string Description { get; private set; }
public BugReport(string description)
{
if (string.IsNullOrWhiteSpace(description))
{
throw new ArgumentNullException("description");
}
this.Description = description;
}
protected BugReport()
{
// Required by EF
}
}CompanyName.ProjectName.Business.Interface.DataRepository
Although my solution is tightly coupled with Entity Framework and I don't make an effort to abstract this (it is pointless), I don't want anything working directly with
DbContext, so I put an interface on top of it, to expose only what I want the consumers of the 'data access' to see.public interface IDataRepository : IDisposable
{
IDbSet BugReports { get; set; }
}
public interface IDataRepositoryManager : IDataRepository
{
void Save();
}In CompanyName.ProjectName.Infrastructure.EfRepository
public class EfDataRepository : DbContext, IDataRepositoryManager
{
public IDbSet BugReports { get; set; }
public EfDataRepository() : base("dataRepositoryConnection")
{
}
public void Save()
{
this.SaveChanges();
}
}CompanyName.ProjectName.UI.MVC
What I like most about this architecture is that I can just do this:
```
public class HomeController : Controller
{
private DataRepositoryFactory dataRepositoryFactory;
Solution
If you are exposing the dbset and allowing the clients (users of the class) to write queries, there will be queries all over the place. If you decide at some point to replace a certain operation with a stored procedure instead, for performance reasons, you have to find those queries everywhere. Or if you introduce a soft delete column for a certain table, you have to find all queries to exclude those records. I wouldn't expose dbsets.
If you don't want the presentation tier to go right against the repository but through another layer, you can create a layered diagram in Visual Studio and enforce which layer can talk to which as shown in https://msdn.microsoft.com/en-us/library/dd409395.aspx
During compilation it will generate errors if the presentation layer is referencing the repository layer.
If you don't want the presentation tier to go right against the repository but through another layer, you can create a layered diagram in Visual Studio and enforce which layer can talk to which as shown in https://msdn.microsoft.com/en-us/library/dd409395.aspx
During compilation it will generate errors if the presentation layer is referencing the repository layer.
Context
StackExchange Code Review Q#148118, answer score: 3
Revisions (0)
No revisions yet.