How to extend POCOs of the Entity Framework by encapsulating business rules?

-5

I'm developing a 3 layer system. My initial intention was to expose the business layer entities to be used in the EF code first.

I want to do this so that I can persist (in memory) entities so that they are managed by DbContext and do not need to fetch the same entities in each part of a request , which does not it would be possible to use DTOs.

  

Example: Create a document. To do so, the user must be allowed to create documents, and the document has a relationship with the creating user.

     

So, in dealing with this case, I would need to first check the user's permissions by searching this in the database. Then you would need to use the same user in creating the glossary.

(* Simplified example, just to illustrate the situation)

In the example above, if I use DTOs between the repository and the business layer, each trip must be isolated, and I would need to fetch the user twice (or give attach and change 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 classes inherited from the entities used by DbContext in the business layer.

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

How can I do this?

    
asked by anonymous 07.08.2015 / 19:05

2 answers

8

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

  

I'm developing an ASP.NET MVC 3-tier system. My initial intention was to expose business layer templates to be used in the EF code first.

This is alarming to read. See how many times I've already had to say that no repository is implemented over Entity Framework, which is already a repository .

Another thing is this "exposition of business layer models". In ASP.NET MVC, what they 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) entities so that they are managed by DbContext and do not need to fetch the same entities in each part of a request , which does not it would be possible to use DTOs.

     

Example: Create a document. To do so, the user must be allowed to create documents, and the document has a relationship with the creating user.

     

So, in dealing with this case, I would need to first check the user's permissions by searching this in the database. Then you would need to use the same user in creating the glossary.

You probably do not understand how DbContext works. With each request it is renewed, precisely because the idea of persisting in memory is terrible and can cause conflicts. Each request has its DbContext , and even the idea of going to the bank with each request is not bad.

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

Still, if you want something faster than the bank, a cache key-value 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 classes inherited from the entities used by DbContext in the business layer.

     

Of course that would not work. So I do not know how. I can use extension methods, but my models are more complex than this, and would have several properties beyond methods (hence my intent 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 the perfectly avoidable practices of ASP.NET MVC, possibly by wanting it to behave like a DDD:

  • Deploy a repository over Entity Framework (which is already a repository);
  • Implement a business layer in a framework that has a similar design pattern ( Controller );
  • Treat Model as a POCO or as DTO ( and that they are neither a thing nor another );
  • Complicate what does not need to be complicated.

I suggest you rethink this whole project or abandon ASP.NET MVC once and for all. I think he's going to mess you up more than help.

    
13.08.2015 / 21:35
0

The solution is simple: members internal .

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

    
13.08.2015 / 21:12