I'm experimenting with a web api in .NET Core 2, where I try to seperate concerns cleanly like in the examples here: https://msdn.microsoft.com/en-us/magazine/mt703433.aspx
One thing I am wondering about is: When using repository interfaces to set/get data, should the data types also be interfaces?
Example (reduced to emphasize the question):
public class ProjectController : Controller
{
IProjectRepository _repo;
[HttpGet]
public IProject GetProject([FromRoute] string key)
{
return _repo.GetProject(key);
}
}
public interface IProjectRepository
{
IProject GetProject(string key);
}
// Implementation based on Entity Framework
public class EFProjectRepository : IProjectRepository
{
private SomeEfContext _context;
public IProject GetProject(string key)
{
return _context.Projects.SingleOrDefault(p => p.Key == key);
}
}
public interface IProject
{
string Key { get; set; }
string Name { get; set; }
}
// EF specific implementation
public class Project : IProject
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Key { get; set; }
public string Name { get; set; }
}
My reason for doing it is, that if I don't, then the EF-implementation specific field Id will "bleed through" into the controller, which I do not want. As I said, this example is very simple, there are reasons for this Id field to be present - it becomes more obvious, when the example is extended with associated DTO's like "Task" etc.
Is there a better way to do this?
DTOs may inherit properties from multiple interfaces and using interfaces may reduce casting data between components and modules, especially in the boundaries of a single solution. Also, rules are often applied on interfaces, so DTOs should use them.
DTO is really powerful. One use is to compose data from multiple objects to be transported. The second use is to hide your data object details away from the rest of the application and this can give you the ability to change the data objects.
Transfering data using Dtos between "local" services is a good practice but have a huge overhead on your developer team. There is some facts: Clients should not see or interact with Entities ( Daos ). So you always need Dtos for transferig data to/from remote (out of the process).
DTOs are inside Domain Layer... I think it really depends on where you intend to use those DTOs. For example, if the DTOs will mainly used by the frontend that relies on some private APIs then I would put the DTOs into the UI layer as other parts of the system do not need to know about those DTOs.
I haven't seen a DTO Interface, you could use it though if you have different clients with common properties. The problem I see is that you are mixing up between Entities (your Business Objects) and DTOs (what you send/receive from clients).
Normally, the Controller, being a client, would not know of the Repository layer. This should be knowledge of the service layer.
If you will only have a single data access layer that uses Entity Framework and you aren't planning on leaving it aside, I would recommend not to have a Repository layer at all, since it already implements both Repository (DbContext
) and Unit Of Work (DbSet
).
A standard SOLID architecture would look something like this (each being a separate project):
string
, int
, etc) or DTOs, and returns DTOsNotice that only the domain/business layer actually sees the Entities that represent your database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With