How To Design BLL in ASP.NET MVC

asp.net-mvcbusiness-logicbusiness-ruleslayers

I'm trying to design a N-Tier Solution for my existing WebAPI project.

I have a WebAPI project where, as of now, all the business logic are written in the controllers and the data validation are done by annotations.

This is now leading to duplicate code across controllers when I'm trying to implement same logic.

So I thought of moving my Business Logics to Business Layer. But I'm mostly facing challenges in returning Business Validations to controller.

For E.g I have a code portion in controller like

//Check if User is adding himself
            if (RequestUser.Email == model.Email)
            {
                return BadRequest("Email", "You cannot add yourself as an User");
            }

Now how do I return BadRequest from Business Class Methods?

And it's getting tough when the next line of the controller is

IdentityResult result = await UserManager.CreateAsync(user);

                if (!result.Succeeded)
                {
                    return result;
                }

So I cannot return both BadRequest & IdentityResult from same method. Also BadRequest, ModelState is not accessible in controllers. Ofcourse I can add System.Web.Mvc there in BLL, but would that be a good idea?

Another thing that I'd like to know is, I'm just creating Methods inside BLL's which are taking ViewModels that I receive in controllers. Is that a good idea for existing project? Or should I create DTO's (same as like Models) in BLL and use AutoMapper to map the properties and let BLL operate on DTO's instead of passing ViewModels.

I think the latter would be more extendable, but would require more time.

Lastly, if you do suggest me to go with DTO's, then I have to change at BLL DTO's as well as in Model when introducing new properties, isn't that a bad idea? Code is then duplicating here too. On other side, as of now, I change all the related ViewModels too (sometimes 2-4) (which I think is not the right approach) when adding a new property to Models.

So what's the right approach?

Best Answer

There are several ways you can approach this.

  • return some value that indicates an error condition, such as null.

  • throw an exception.

  • wrap your DTO in some sort of "maybe" object that returns both your DTO and some status information.

  • Use the Unit of Work pattern.

The right approach is the one that most effectively meets your specific requirements.