Colleagues, good afternoon!
Why has no one mentioned the UnitOfWork pattern? Pattern repository becomes very convenient to use if:
- this pattern GenericRepository;
- if necessary, you can add specific repositories (I call them ConcreteRepository;
- and of course, if all of these controls UnitOfWork;
If you use this link You have:
- if a lot of entities and there is a GenericRepository, you do not need to produce a repository for each entity, it is sufficient to do this: var unit = UnitOfWork.Repository();
- the paragraph above automatically solves the problem "how to select data from a 2-3-4-... table" with the repositories you work with DbSet in EF (by the way, the DbContext from EF, in fact, implements the UnitOfWork and GenericRepository pattern);
- automatically solved the issue of expansion of your repository methods on everyone (ie, the need to list the logs for a specific user - adding new method to the repository GetLogsByUserId) - no need to wind the repository with new methods, it is sufficient to do this: var unit = UnitOfWork.Repository().GetQuery(e => e.UserId == targetUserId) or var unit = UnitOfWork.Repository().AsQuaryableQuery(e => e.UserId == targetUserId) (GetQuery AsQuaryableQuery methods and methods that the entity UnitOfWork that return IEnumerable or IQueryable, respectively);
- if the methods SaveChanges/Commit implemented in UnitOfWork (UnitOfWork and manages the transaction database), then you have solved the problem of data consistency - UnitOfWork or confirm all changes (Commit), or rolls back in case of errors (Rollback);
Or am I the special class to have in kotroman will all repositories(the dbContext as a direct)?
Think correctly - this special class is the UnitOfWork. He is "just like dbContext", the only way you abstract from any EF, NHibernate or other ORM. In the end, your business logic on the drum, which ORM you use.
If I need 1 controller/service 1 repository? I 1 them to connect? maybe I need 15.
Simply connect 1 UnitOfWork (better to do it through dependency injection - DI - DependencyInjection using an IoC container, such as Autofac, Ninject, Unity. Autofac personally I like more though, because he is the most adequate and clear documentation than Ninject and especially Unity [no, this is not a topic for holivara "who is better: Autofac/Ninject/Unity/... - this is all my personal experience]).
And the main question. Do I need to apply this pattern if you don't use unit testing, or not using it to cover 100% of all the code and only certain helpers? After all, to switch to a different database it will be enough to change providers if you use ef, and if you use the ORM you are unlikely to completely refuse. Why write a bunch of code "in advance" with the principle of "but suddenly we change the dB/OS", but it is likely to reduce code changes compared to a full rewrite of the project. But if you're sure that the OS and dB will not change?
In any enterprise project, it is necessary to think ahead, even if it is the "little online store". Because in a year this small online shop can become a normal business with very high turnover and profit, and then, if You don't have a good abstracted architecture
, if you don't have modularity
, any new task will be implemented with a large number of crutches, and any new task will lead to instability in the system and to increase the degree of the regression (tested!). But if you as the architect will invest in the development of your system modularity and abstraction components, you thereby already make life easier for yourself in the future, and this means that after some time any task of changing the system will be solved faster, more reliable, and means you can take as a developer for it more money (because the cost of the new changes will be much lower). And if you're unit-testing will use when developing, you thereby reduce the risk of regression in the behavior of your system, which again reduces the cost of developing for you personally. Believe me, when the system has at least the modularity and abstraction of the components from each other (i.e., any component depends on the abstraction - the interface or abstract class, and not implementation - specific class), then such a system will be fun.
DBMS change is not such a common practice, but from the ORM (and EF in particular) to abandon in favor of performance is a real case load increases.
- absolutely agree with You about this.
it is a theme referred to the principle of single responsibility. 1 component - 1 responsibility. Noticed that myself - if you follow at least this principle, then automatically the system becomes modular. And if there are modules, it is possible to reduce the degree of connectivity of system components using abstractions (interfaces and abstract classes). And if there is an abstraction between the components, the unit test will be only joy. Moreover, a component can be both a class and a project. For example, in a separate project, you can make some kind of module system, then the project can be connected to another system during development. This improves the degree of code reuse (why 2 times to do the same thing?).
also pointed out in the comments, in some cases, the repository can not be used. Add: in non-enterprise solutions. For example, you are doing some simple little website for myself. Or for a friend. Or just for learning new technologies.