2

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...

1 Answers1

-1

Question 1

Your domain models should represent your database and be clean and light as to transport data easily from your database to any part of your application. If you add logic to your models, they quickly become bloated and heavy so that every time you new up an instance of each domain model, your logic comes along with it whether it's going to be used or not!

If you start putting all of your logic into your domain models, you'll soon realise that you want to access the properties of other domain models and then you have to start passing them into each other and it soon gets messy. The only thing it is useful for is that you only ever write your code once, but that's where the beauty of separating your logic out into a service layer becomes apparent.

The beauty of having a service layer is that each service can contain the logic to perform specific functions or groups of functions on your DTOs and (lightweight) domain models, they only need to be written once and the same code can be used multiple times throughout your application. You can interface the services out and add each service as dependencies to your controllers as and when required, so that you only expose them to the specific parts of the logic within your services that each controller actually requires and no longer to every piece of logic that you might have gone and written into your domain models before.

Having a service layer should significantly reduce the amount of code that you have in your controllers too, because your business logic will be performed in your services and the controller actions will just serve to pass values up to your services for processing and map them back to your view models.

Question 2

Depending on what you are doing (if you're not using multiple threads in a request), generally you should have a single new DbContext per HTTP request - this can be configured using most DI containers. I would get yourself an Interface for the DbContext and configure it in your MVC application layer and inject it upwards into your service layer.

...

Community
  • 1
  • 1
Luke
  • 22,826
  • 31
  • 110
  • 193
  • Sorry, that's completely wrong. DDD propagates rich models which are not a representation of the database. That's called persistence models. It should be notetd though that rich domains using with ORM or persistence models are bit difficult topic. DDD with rich domains best works with event sourcing (and CQRS). Having models that only carry data and no logic leads to bloated and hard to maintain services where the model can easily end up in an inconsistent state – Tseng Aug 01 '17 at 16:23
  • It's not wrong just because it doesn't match a particular methodology. This question isn't _really_ suitable for SO, cause it's not specific and it's very subjective. Thanks for your 2 cents though, I hadn't even heard of DDD. – Luke Aug 07 '17 at 10:27