What does Service Layer do? Repository Pattern / Unit Of Work


Do i need Service Layer? From my point of view/understanding.

Presentation Layer = UI

Business Logic Layer = Domain/Entities, Interface and (should DTO resides here)?

Data Access Layer = Implementation of Repository Pattern, CRUD.

Service Layer = ???

If the BLL has Domain/Entities? what layer does business validation belongs to? 

From what i know and searched. Entites and DTO is plain.

 

 


Asked by:- EmmanuelReal
0
: 254 At:- 6/25/2018 12:42:05 PM
C# ASP.NET Repository Pattern






3 Answers
profileImage Answered by:- vikas_jk

If you will look into the basic definition of Repository patter/Unit of work it would be as below

Unit of Work Pattern

The Unit of Work pattern is used to group one or more operations (usually database operations) into a single transaction or “unit of work”, so that all operations either pass or fail as one. 

Repository Pattern

The Repository pattern is used to manage CRUD operations through an abstract interface that exposes domain entities and hides the implementation details of database access code.

Now, let get into details of it, work means performing some task.  From a software application perspective Work is nothing but inserting, updating, and deleting data. For instance let’s say you have an application which maintains customer data into a database.

So when you add, update, or delete a customer record on the database it’s one unit. In simple words the equation is.

1 customer CRUD = 1 unit of work

The DataContext or ObjectContext is the Unit of Work.

So, your DAL will save, delete and retrieve objects and your DataContext/ObjectContext will keep track of your objects, manage transactions and apply changes.

For "Service Layer = ??? If the BLL has Domain/Entities? what layer does business validation belongs to? "

Yes, the service layer is an overhead if you don't have any business logic there. Layered architecture looks like an overhead when a layer (in your case service) is not doing much. But a layered architecture provides your loose coupling which is generally good for adapting requirements in future.

If you can guarantee that you will never need to do anything in service layer except data copy from repo to model then you can remove the service layer in your design. However if your application is basic then you don't have to worry about adding another layer for performance or other reason.

Personally I will keep the service layer and (depends on the technology) will implement a generic DAO/Repository layer.

Application flow control logic belongs in a controller and data access logic(DAL) belongs in a repository. In that case, you can place your validation logic in a service layer.

A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer. The service layer contains business logic. In particular, it contains validation logic.

For example, the product service layer in example below which has a CreateProduct() method. The CreateProduct() method calls the ValidateProduct() method to validate a new product before passing the product to the product repository.

using System.Collections.Generic;
using System.Web.Mvc;

namespace MvcApplication1.Models
{
    public class ProductService : IProductService
    {

        private ModelStateDictionary _modelState;
        private IProductRepository _repository;

        public ProductService(ModelStateDictionary modelState, IProductRepository repository)
        {
            _modelState = modelState;
            _repository = repository;
        }

        protected bool ValidateProduct(Product productToValidate)
        {
            if (productToValidate.Name.Trim().Length == 0)
                _modelState.AddModelError("Name", "Name is required.");
            if (productToValidate.Description.Trim().Length == 0)
                _modelState.AddModelError("Description", "Description is required.");
            if (productToValidate.UnitsInStock < 0)
                _modelState.AddModelError("UnitsInStock", "Units in stock cannot be less than zero.");
            return _modelState.IsValid;
        }

        public IEnumerable<Product> ListProducts()
        {
            return _repository.ListProducts();
        }

        public bool CreateProduct(Product productToCreate)
        {
            // Validation logic
            if (!ValidateProduct(productToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreateProduct(productToCreate);
            }
            catch
            {
                return false;
            }
            return true;
        }

    }

    public interface IProductService
    {
        bool CreateProduct(Product productToCreate);
        IEnumerable<Product> ListProducts();
    }
}

Now, let's add the service layer, now we use the service layer instead of the repository layer. The controller layer talks to the service layer. The service layer talks to the repository layer. Each layer has a separate responsibility.

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        private IProductService _service;

        public ProductController() 
        {
            _service = new ProductService(this.ModelState, new ProductRepository());
        }

        public ProductController(IProductService service)
        {
            _service = service;
        }

        public ActionResult Index()
        {
            return View(_service.ListProducts());
        }

        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude = "Id")] Product productToCreate)
        {
            if (!_service.CreateProduct(productToCreate))
                return View();
            return RedirectToAction("Index");
        }

    }
}

references

https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/models-data/validating-with-a-service-layer-cs

https://www.codeproject.com/Articles/581487/Unit-of-Work-Design-Pattern

More links which may help

http://jasonwatmore.com/post/2015/01/28/unit-of-work-repository-pattern-in-mvc5-and-web-api-2-with-fluent-nhibernate-and-ninject

https://www.dotnettricks.com/learn/mvc/implementing-repository-and-unit-of-work-patterns-with-mvc

Hope it helps.

1
At:- 6/25/2018 5:12:25 PM


profileImage Answered by:- vikas_jk

Well, basically creating a new layer helps us to create abstraction layer in our project ,reusuable code, separation of code, now looking at your comment, I don't think we need that level of abstraction, but it depends on your needs also, if you are going to use same logic again and again go for it, create that validation/service layer, I have seen projects in which most people create that layer of validation, mainly it depends on you and your project requirements.

1
At:- 6/26/2018 7:04:44 AM Updated at:- 6/26/2018 7:05:27 AM


profileImage Answered by:- EmmanuelReal

Based on the example? If the validation is simple is it okay to  put the entities like Required Date Annotations and only complex validation in service layer? how about if i check the product existence and only delete it when it is still existing, here the example:

public void DeleteProduct(Product product){

var checkProductId = context.Products.Where(p => p.Id == product.Id && !p.IsDeleted).Selected(p => p.Id).FirstOrDefault;

if(checkProduct > 0)

{

//delete repository; if the product is still existing.

}

else

{

//throw error

}

}

-is this kind of validation above should be in service layer like checking if the product is existing before deleting the product? 

0
At:- 6/26/2018 2:44:28 AM





Login/Register to answer
Or
Register directly by posting answer/details

Full Name *

Email *




By posting your answer you agree on privacy policy & terms of use