I know there are a lot of threads around the topic, but I didn't find any post that satisfied me and really explains how to develop business logic within entity framework. So in this post I want to sum up what I got by reading various other posts and then ask you to help me cleaning my mind.
Entities: These are my classes wich are mapped to tables in the database like User, Transaction, Order and so on. These are POCO objects (and I use them with Code-First approach).
Domain Model: This is the place when the business logic should be. It took me quite a while that the Domain Model isn't the sames as the entites of EF.
Service-Layer: I figured out that a service layer is not needed in the first place. It can be used to bring some stuff into it, but the in general the business logic should be in the model. So better let that out
Repository-Layer: Ok we can write a repository with CRUD-Methods like IEnumerable GetUsers()
which make testing easier, but on the other side we'll lose the whole LINQ features and it's a lot more writing. For testing I can also mock the EF Framework, so for me a repository layer is out.
Unit-Of-Work: The DbContext itself is a Unit-Of-Work. So I don't have to code anything special here, I just have to pass the DbContext to all my methods and call SaveChanges when done.
Lazy-Loading: Sometimes I did use it, sometimes I did use Eage Loading. But in the meantime I figured out, that Lazy-Loading is a must, when you want to do the Unit-Of-Work stuff and keep your code clean. When you are in a method and get some code passed into that's from another method wich in turn got this from another method... you just want to access the properties. You can't care if the data is in there or not. It has to be loaded automatically. So I am wondering how to do that without any lazy loading.
DbContextScopes: As in other posts discussed we shouldn't use DbContext on application instance, we shouldn't also use it per request. Instead we should create one DbContext for the current task and pass it to all the methods needed. This can be made easier using [DbContextScopeFactory][1].
Dependency Injection: I always should use DI to inject needed stuff in the constructor. It makes sense because when we have a unit test, we can just put in mock-resources. I also read that attribute injection is not so good and should'nt be used.
Transactions: should'nt be used anymore because they have many issues. Instead stick with Unit-Of-Work (which internally uses a transaction?!) and model your architecture this way.
So now I am wondering how to really use that stuff.
Question 1: Model = Entity?
Should we create some kind of seperate domain model or can this be included in the entity model? An extra domain model seems way to much code I think. Why not write the logic into the entities? What are the issues?
Question 2: How to get DbContext?
When I add an entity then I do not want to add infrastructure stuff like
order.Lines.Add(new OrderLine(product, qty, text));
and not
order.Lines.Add(new OrderLine(dbcontext, product, qty, text));
Maybe attribute dependency injection is a solution, but as said that is also not a good pattern...
Aucun commentaire:
Enregistrer un commentaire