2

I'm developing N-Tier application in C#. Server side consists of this layers:

  • Data access layer (EF Code First Entities and DbContext)
  • Business layer (contains all business logic and objects)
  • WCF Service layer (per-call instanstiated services that expose some operations from business layer)

Now client requests are processed in this way:

  1. Client creates Request DTO and sends it to Service layer
  2. Service layer maps this DTO to business object and calls BL method
  3. Business layer does something useful, makes requests to DAL, and then returns some business object to service
  4. Service layer maps business object to DTO Response and returns to client

It works nice despite code duplication which is mitigated by Automapper. The actual problem is this:

Client shows same objects in different views: grid, form, etc. For example, grid(list) view requires only Id and Name from User object, while Form(details) view needs every User's property. But Business layer knows nothing about views. It can only provide full UserBL object to Service calls and then it's the Service responsibility to map this UserBL to UserListDto or UserDetailsDto. And for some heavy objects, fetching extra fields from DB become a performance issue.

So, should Business layer provide different methods for different client operations? I don't like this solution because it looks like domain logic polluting, but I don't know what else could be done.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
v1rusw0rm
  • 117
  • 2
  • 8
  • Have you considered using some caching on the client? Especially if you are getting the same information from the service layer all over again. How volatile is this data? – Darin Dimitrov Dec 15 '15 at 21:16

1 Answers1

3

Client shows same objects in different views: grid, form, etc. For example, grid(list) view requires only Id and Name from User object, while Form(details) view needs every User's property. But Business layer knows nothing about views. It can only provide full UserBL object to Service calls and then it's the Service responsibility to map this UserBL to UserListDto or UserDetailsDto. And for some heavy objects, fetching extra fields from DB become a performance issue.

I usually return different representations of a business entity depending of the type of action that is made in the BL. For instance when searching a return a search representation of user which just contains the minimal set of properties required to identity a user. When fetching a specific user I return a complete business object.

Regarding your issue with code duplication. It is not duplication. Those different representations of a user have different responsibilities.

  • DTO: Responsible of transferring a user and creating a loose coupling between the business layer and the consumer
  • BO: Responsible of encapsulating and performing business operations
  • DB entity: Responsible of making the BO object persistent ignorant

Thus if you would use only one representation of a user you would merge all those responsibilities and therefore have to do sacrifices in good design to be able to use it everyone. The only really gain is that you have to write a few lines less code. Keep that in mind when you start to maintain the released application. You saved a few lines, but got a lot harder application to maintain.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • "I usually return different representations of a business entity depending of the type of action that is made in the BL." I think that's what I will do. There will be some paging\sorting logic in BL anyway, even if it's not pure domain logic (or am I wrong?) – v1rusw0rm Dec 16 '15 at 08:25
  • "Regarding your issue with code duplication. It is not duplication. Those different representations of a user have different responsibilities." That's the exactly what I think when making different objects for different layers even if this objects look very similar. I didn't explain it in the question because it's a little out of question scope. And I just mentioned it because some developers don't like it arguing that it violates DRY principle. – v1rusw0rm Dec 16 '15 at 08:25
  • That's great that you also know that. Just as you I've meet a few devs that want to use the same object. – jgauffin Dec 16 '15 at 08:38