How to extend Pocos from the Entity Framework by encapsulating business rules?

Asked

Viewed 420 times

-5

I’m developing a three-layer system. My initial intention was to expose the business layer entities to be used in the repository (EF code first).

I want to do this so that I can persist (in memory) the entities, so that they are managed by DbContext and no need to seek the same entities in each part of a request, which wouldn’t be possible if you were using Dtos.

Example: create a document. To do so, the user needs to have permission to create documents, and the document has a relationship with the creator user.

Thus, when treating this case, I would first need to check the user’s permissions, searching it in the database. Then you would need to use the same user when creating the glossary.

(*Simplified example, only to illustrate the situation)

In the above example, if I use Dtos between the repository and the business layer, each trip should be isolated, and I would need to fetch the user twice (or attach and change the status, but that’s not the point).

So I wanted to keep entities in the business layer, without using Dtos. But I also want to encapsulate the functionalities of BL. My initial plan was to use, in the business layer, classes inherited from the entities used by DbContext.

Of course, that wouldn’t work. So I don’t know how to do it. I can use extension methods, but my entities are more complex than that, and would have several properties besides methods (hence my intention to isolate this complexity from the business layer).

How can I do that?

2 answers

8

This question is a collection of problems. Even if you don’t consider it, I will use it as a guide to what not to do in an ASP.NET MVC application.

I’m developing a 3 layer ASP.NET MVC system. My initial intention was to expose business layer models to be used in the repository (EF code first).

This is alarming to read. See how many times I’ve had to tell you not to implement repository on top of Entity Framework, which is already a repository.

Another thing is this "business layer model display". In ASP.NET MVC, what are exposed are Controllers, which return various types of formats, such as HTML, XML and JSON.

I want to do this so that I can persist (in memory) the entities, so that they are managed by DbContext and no need to seek the same entities in each part of a request, which wouldn’t be possible if you were using Dtos.

Example: create a document. To do so, the user needs to have permission to create documents, and the document has a relationship with the creator user.

Thus, when treating this case, I would first need to check the user’s permissions, searching it in the database. Then you would need to use the same user when creating the glossary.

Most likely you don’t understand how a DbContext. With each request it is renewed, precisely because the idea of persisting in memory is bad and can cause conflicts. Each request has its own DbContext, and that’s not why the idea of going to the bank at every request is bad.

You probably don’t know the concept of filters, which is one of the great advantages of MVC. Permissions are seen at the level of application, and not at bank level. Here I explain several ways to do this. In your case, it would be a more specific filter that would work together with the context.

Still, if you want something faster than the bank, one cache value key like Redis is more appropriate.

So I wanted to keep entities in the business layer, without using Dtos. But I also want to encapsulate the functionalities of BL. My initial plan was to use, in the business layer, classes inherited from the entities used by DbContext.

Of course, that wouldn’t work. So I don’t know how to do it. I can use extension methods, but my models are more complex than that, and would have several properties besides methods (hence my intention to isolate this complexity from the business layer).

A Model is not a DTO. It is not an anemic entity. You can write behaviors and validations for the Model. There is no need for this separation. The gain is zero.

Finally, you incur all of ASP.NET MVC’s perfectly avoidable practices, possibly by wanting it to behave like a DDD:

  • Implement a repository on top of Entity Framework (which is already a repository);
  • Deploy a business layer in one framework which has a similar design pattern (Controller);
  • Deal with Model as a POCO or as a DTO (and are neither one nor the other);
  • Complicate what doesn’t have to be complicated.

I suggest you rethink this whole project or abandon ASP.NET MVC for good. I think it will more disturb you than help.

  • +1 for Implementar um repositório em cima de Entity Framework (que já é um repositório);, I even questioned this in a question mine, but I confess that the answer did not convince me much.

  • @Thanks for pointing out. I can give you another answer there if you want.

  • A new opinion is always welcome

  • First, I’m using ASP.NET MVC, but I can and will use other front ends. Second, I do not want to persist entities beyond a request, I wanted to persist within a request. Finally, maybe I’m wrong, but my relationships will be quite complex on the BD side, and I’m going to need to attach complexes, and I want to, I need to delegate this to a layer by part (repository).

  • Not disagreeing of nothing I said, I just don’t know how it applies to the question How to extend Pocos from the Entity Framework by encapsulating business rules?, and probably was due to lack of clarity in the question.

  • Well, then good luck with your implementation. It’s up to me to just point out what’s wrong. Anyway, I’m going to use this question a few times, because it synthesizes a lot of the problems of modern ASP.NET MVC applications that I see around.

  • No, I didn’t really want to answer her question, because she has neither foot nor head. The idea is to use it for other didactic purposes. Feel free to go against her.

  • I don’t see how ASP.NET MVC influences the architecture of the other layers. How can a question about architecting the relationship between BL and Repository show a common error in a presentation technology? Imagine the same question for a console app that is. No matter the presentation.

Show 3 more comments

0

The solution is simple: members internal.

Exposing domain models or entities to be used by the repository (and the presentation layer when they fit), and exposing exclusive members to business logic such as internal, only becoming visible within business logic.

  • Hello! If I understood your answer (and also your question) correctly, all you wanted to know was about visibility or encapsulation of class members. In this case, your question is unnecessarily complex, as all those details about storing entities in memory, permissions, and others are irrelevant to the answer. This confusion probably left room for the other answer. My suggestion is that you edit your question leaving only information relevant to your visibility issue. It would be interesting to include a piece of code to illustrate what you are saying.

  • @utluiz After finding a way to do, really every part of the question that does not feed the answer could be eliminated. But I hoped to find others means of doing, maybe more right. My answer answers, but is the only way? The best way?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.