Replies: 16 comments
-
I prefer having a repository , with a repository I can test my commands and query in unit tests. |
Beta Was this translation helpful? Give feedback.
-
I generally prefer to have repository abstraction living in the application layer and implementation in the infrastructure layer. One of the benefits of doing so is that you don't have to have a dependency of |
Beta Was this translation helpful? Give feedback.
-
On the one hand it is convenient to have a repository where you can store all your queries for re-using inside commands and queries. E.g. you may write the same or similar query inside Mediator's queries many times and it is violation of DRY principle. Will be cool to have all queries stored in the one place and you can re-use these. |
Beta Was this translation helpful? Give feedback.
-
+1 but I usually have the repository interfaces in the domain model. This is what Eric Evans suggested in his book. It allows me to use the interfaces in the domain (yes that means they aren't pure but so what) and I don't need to rely on the fact that somewhere somehow some technology like EF is tracking changes. |
Beta Was this translation helpful? Give feedback.
-
Domain isn't the good place from my point of view. Because domain contain enterprise wide logic and not just application specific logic. As this domain project gets shared across other project as well, and their they will have different application layer with different architecture. By putting repository abstractions in domain, you are forcing other projects application layer to implement them although they might have different way or strategy. And also repository is one of the methodology of data persistent , and I don't want my domain should know about it and not even abstraction. |
Beta Was this translation helpful? Give feedback.
-
EF core implements repository and unit of work pattern. The repository is supposed to handle persisting from domain layer to data layer and store that in memory. The unit of work guarantee all entities are persisted in 1 transaction. Change tracker is one of the functionality to handle that kind of task. The benefit of change tracker is, we can rely on it to handle domain event. If you choose to implement repository pattern and not using EF core anymore, you might need to implement domain event as well. Take a look at MembershipReboot as an example. This class decorates another repository that handle persisting to actual storage. |
Beta Was this translation helpful? Give feedback.
-
Is Repository an anti-pattern in Ef Core? |
Beta Was this translation helpful? Give feedback.
-
I will still implement this so that I can easily mock my repositories in the application layer and test them, without needing ef! |
Beta Was this translation helpful? Give feedback.
-
I don't want to make it complex going forward, so having repository abstractions is valid and good rather than over-engineering every stuff! |
Beta Was this translation helpful? Give feedback.
-
Also it is not known as good practice to use Repository Pattern with EF Core (because it has built in repository and unit of work) you should be using it if you need. If you want your application not being ORM dependent, using some design patterns like aggregates or some testing and mocking situations are the examples of when it is good to use it. Here is an article about preferring query objects over repositories. |
Beta Was this translation helpful? Give feedback.
-
Disagree. Using a concrete repository is about encapsulating the operational concerns of communicating with a database to abstract technology concerns from your domain. Whether you achieve this through repositories or other means is a different matter - but using EF Core directly in domain is a bad idea to me. Unless you decide you're going full in on EF and you dont mind. But even then it makes unit testing harder. Query object looks like it aims to do the same thing without abstraction. |
Beta Was this translation helpful? Give feedback.
-
And @CraigComeOnThisNameCantBeTaken it really depends on the usage and expectation. If abstracting domain/application layer from ef core is needed, then making repository pattern is good choice. Of course, you need to think the reason why. If it is for unit test purpose, I will choose in memory db, builtin feature from ef core. I don't to mock my data layer anymore, cleaner code and less effort when writing unit test. |
Beta Was this translation helpful? Give feedback.
-
Your point about using EF directly in the app layer makes sense to me since I think the app layer should be integration tested rather than unit - and at the integration level you probably want an inmemory db anyway. My only issue there is that I dont want to be tied to EF and so I dont want to rely on their change tracker. And I dont want my domain model to be my ef entity model either. I guess automapper or similar... Would like to hear your opinion if you get time please :) |
Beta Was this translation helpful? Give feedback.
-
Can you elaborate more? I don't understand, which part that sounds over engineering? I think this template is good enough for utilizing ef core feature, such as storing domain event, keeping that in domain layer. In infra layer, we can dispacth all domain events right exactly after state is persisted. We can do it easily using efcore with change tracker feature. Without efcore, I'm thinking to implement that my self. This sounds over engineering to me for building the replacement. Especially for simple microservice. I would prefer to utilize existing library which is mature enough. |
Beta Was this translation helpful? Give feedback.
-
Probably that's the best reason: not using efcore for data layer. I tried that before using dapper, creating repository for every entity access. And ends up with more effort when mocking repository which doesn't worth. And you're right, domain model shouldn't be tied up with efcore entity. We can achieve this using mapper library like automapper, mapster, etc. But think about this when querying: from data layer with their own entity classes, and then mapped to domain model, and then mapped to app response. Of course, we can skip domain model for this case, and (probably), domain layer isn't needed at all. Perhaps this sounds over engineering, remapping object 3 times, and performance might drop. I'm open suggestion for this. Do you have public repo as an example. I would be keen to learn my failure from the past. These are my concerns when using repository pattern:
|
Beta Was this translation helpful? Give feedback.
-
@fakhrulhilal I dont have a public repo, and everything you said is true. I also feel mapping 3 models is painful and gives so much boilerplate, but I dont have a DTO for responses, I return the domain model (maybe with some ignored properties like invariants) as a resource. Automapper then can map both properties and dependencies from the DI container so I think you could avoid factories at least. for your concerns: When I mock the repository I usually use Test Mothers which are static classes that return objects. I setup a method that returns reasonable defaults and then I add more methods to customise this as needed. I would need data at some point regardless even if it was just inserting data to the database. I dont think there is more maintenance for the repository. I use an in memory db for the repository and dont try to unit test that - not a mocked db but in memory. If anyway this separates domain from database technology and so reasons for change are separated which to me means less maintenance. When I write tests for the repositories I might write an interface holding all the test methods and different repository implementations (ef vs dapper) would implement that. I still write tests on the database code using a real / in memory database so column names are caught. Plus im able to test it independently without the rest of the application. This is just what I do so dont take it as me teaching you from your failure - this could be me walking towards failure. There is boilerplate, some of it doesnt please me, but I know I can change technologies and business logic independently. If I want to vertically partition tables EF wont make my application layer look crazy, and if I want to switch to dapper its incredibly easy (which I have done, and it was painless). |
Beta Was this translation helpful? Give feedback.
-
hi.
I was a bit confused.
I read somewhere that the Repository template has been implemented inside Ef Core and we no longer need to use Repository in asp core and only use services in the Application layer.
For example, a folder should be created for the user and all tasks and services related to the user, such as registration, deletion, etc., should be implemented by these services, which themselves work directly with DbContext.
Is the use of Repository obsolete in clean architecture and Ef Core?
Beta Was this translation helpful? Give feedback.
All reactions