Closed fabercs closed 5 years ago
// get entity via repository
// work with the entity via its methods and properties
// save entity via repository
However, some teams do establish standards that, in order to keep controllers lean, they only call a service layer from the controllers or they only raise events (e.g. MediatR) from controller actions, which are handled elsewhere. So, that's also something to keep in mind.
The whole point of a repository abstraction is to encapsulate the details of how data access is performed. If you have a repository abstraction that includes in its definition details of one particular implementation, it's not an effective abstraction. Hence, you don't want repository interfaces that return SqlDataReader, for instance, because it's going to be very hard to later implement that against an XML file or a web API. The same is true if the interface itself exposes a DbContext.
The book doesn't suggest that all services go into Infrastructure, just the low level implementation details. The calls to EF to perform the delete are low level. The orchestration of deleting multiple things in an object hierarchy, error handling, perhaps unit of work implementation, follow-on work like notifications, etc. is all higher level logic that can go in a Core service (which operates against interfaces). Let me know if that makes sense.
@ardalis Thank you very much for your response, it all does make sense, just a few points,
For exposing DbContext
in IRepository
all the things got engaged (generic repositories with multiple contexts and transactions etc), so did it unwittingly, thanks for your reviews, I will revert it.
For a concrete example of domain-specific repository interface, let's say I have 2 DbContexts
AppDbContext
LogDbContext
and I have IRepository<TEntity>
for AppDbContext, do you suggest me something like this
ILogRepository : IRepository<Log>
and use LogDbContext inside it?
And, no matter what, as long as any repository or uow implementation would be inside Infra, I will always have reference from Web to Infra for now(until built-in container features appears, not willing to stick to external IoC dlls ), am I right?
Yes, something like ILogRepository would work, and you could have your concrete implementation in the Infrastructure project request a LogDbContext. Assuming this is for logging, I probably wouldn't call it a repository, since typically you don't do updates or deletes or even many reads of log entries. If that's the case, a more intention-revealing name might simply be an ILogger. But I don't know your model or application so I could be way off here.
And yes it's normal to have a reference from Web to Infrastructure, but the only place you should be using that reference is in Startup ConfigureServices, typically. It is possible to wire things up without the reference but it requires some work and can make it a little harder to run the application or get set up if you're a new developer unfamiliar with the project structure. So, unless you're having a very hard time keeping your team from using Infrastructure types in Web (outside Startup), it's not something I see many teams doing.
It was just a bad choice for naming the context. Now all is ok, thank you for your efforts.
This is a batch question for guidance at my an ongoing project. Well, I am trying to follow clean architecture structure.
1- First of all, is there any enforcement to not to call generic repository from controllers, which has not services.
IRepository<User>
from Web api controllers? Should I always create a Service Layer for at least a simple query anyway? Or should I build a specific repository that inherits generic repository than use it in controllers as the sample does? From my understanding I can call IRepository2- In my project to use multiple EF Core dbContexts, I have changed my
IRepository<TEntity>
contract toIRepository<TContext, TEnitity>
, to call it from a controller or service. So inside a service ( Project.Core ) or a controller ( Project.Web ) I always have a reference to ( Project.Infrastructure ) thanks to context dependency. I have dependency to these context objects inside at Startup class as well as it is discussed earlier in some issues posted here and eshoponweb repo's. Also, when I need to implement an UnitOfWork pattern I still dependent to context object. So is this a real red line not to get accross which has the only [this argument ] ?(https://github.com/ardalis/CleanArchitecture/issues/18#issuecomment-399950805) Or is it better to try make dbContext object stick to an interface such as IDbContext?3- E.g a user with posts and comments will be deleted completely from application. For that I have an api endpoint like in my controller
So inside my controller, I have an IUserService dependency which handles this process. Where this IUserService's implementation detail should live? Is this a domain service or application service?
According to this passage from Clean Architecture book, it should reside in Infrastructure layer. However inside eshoponWeb project services reside in Core project?
Thanks in advance.