Blog

Filter posts by Category Or Tag of the Blog section!

Apply to request response pattern in your service layer

Sunday, 03 February 2013

Messaging pattern is one of my favorite patterns to use in the service layer! since I've read Pro Asp.net Design pattern by ScottMillett I've been a big fan of patterns and how to apply them, in this article I'm going to talk about request-response pattern.

"Design patterns that are associated in the realm of large-scale distributed applications like SOA systems are often referred to as Messaging patterns. Messaging patterns, like Design patterns, provide standard solutions to complex problems. Messaging patterns tackle the sharing of data in a uniform manner among many disconnected systems." ~@ScottMillett

So let's implement it, I'm going to define the News part of a project that I'm tackling with at the moment, I will just implement two operations, I have defined these methods in INewsService :

CreateNews , GetNews , GetAllNews , UpdateNews , RemoveNews , GetNewsByDate , GetAllArchivedNewsByDate

And I'm discussing CreateNews and GetAllArchivedNewsByDate .So For each of them, I should create a response and a request class. let's begin by creating the messaging classes

 

    public class CreateNewsResponse
    {
       public NewsViewModel PostViewModel { get; set; }
    }

 

This response class that returns a property of NewsViewModel type lets me access the NewsViewModel properties.  and about CreateNewsRequest I usually create a constructor contained newsViewModel as a parameter to make it using the method in service implementation and also Presentation simple

 

    public class CreateNewsRequest
    {
        internal NewsViewModel NewsViewModel { get; private set; }
        public CreateNewsRequest(NewsViewModel newsViewModel)
        {
            NewsViewModel = newsViewModel;
        }
    }

 

Now in INewsService interface, define the CreateNews like this

 

    public interface INewsService
    {
             CreateNewsResponse CreateNews(CreateNewsRequest request);
    }

 

As you can see CreateNews contains a response as an output and a request as a parameter. And as I promised, I Create messaging classes of GetAllArchivedNewsByDate :

 

    public class GetAllNewsRequest
    {
        internal NewsViewModel NewsViewModel { get; private set; }
        internal int Year { get; private set; }
        internal int Month { get; private set; }
       
        public GetAllNewsRequest(NewsViewModel newsViewModel)
        {
            NewsViewModel = newsViewModel;
        }
        public GetAllNewsRequest(int year, int month)
        {
            Year = year;
            Month = month;
        }
    }

 

As you see in the request class I've defined two constructors, first one is the same you saw in CreateNewsRequest and the second one take two parameters (year and month) because I need this constructor in presentation layer that you will see later!

And about response class

 

    public class GetAllNewsResponse
    {
        public IEnumerable<NewsViewModel> PostViewModels { get; set; }
    }

 

It returns an IEnumerable of NewsViewModel cause it maybe has more than one news in a date.

And then in INewsService I have to define the GetAllArchivedNewsByDate like this :

 

    public interface INewsService
    {
             CreateNewsResponse CreateNews(CreateNewsRequest request);
             GetAllNewsResponse GetAllArchivedNewsByDate(GetAllNewsRequest request);
    }

 

Well, about implementing these methods in NewsService take a closer look at NewsService :

 

    public class NewsService : INewsService
    {
        private readonly INewsRepository _newsPostRepository;
        private readonly IUnitOfWork _unitOfWork;
        public NewsService(INewsRepository newsPostRepository , IUnitOfWork unitOfWork)
        {
            _newsPostRepository = newsPostRepository;
            _unitOfWork = unitOfWork;
        }
        public CreateNewsResponse CreateNews(CreateNewsRequest request)
        {
            var response = new CreateNewsResponse();
            var newsPost = request.NewsViewModel.ConvertToNewsPostModel();
            newsPost.CreationTime = DateTime.Now;
            newsPost.NewsSlug = request.NewsViewModel.Title.GenerateSlug();
            _newsPostRepository.Add(newsPost);
             _unitOfWork.SaveChanges();
            return response;
        } 
        public GetAllNewsResponse GetAllArchivedNewsByDate(GetAllNewsRequest request)
        {
            var response = new GetAllNewsResponse();
            var newses = _newsPostRepository.GetAllArchivedNewsByDateQuery(request.Year, request.Month);
            response.PostViewModels = newses.ConvertToNewsViewModelList();
            return response;
        }

 

Notice about GetAllArchivedNewsByDateQuery method, it's defined in the Repository layer and it returns a value by Query Object pattern from the database.

And about ConvertToNewsViewModelList and ConvertToNewsPostModel I've talked about before in the Automapper article, I use the extension method to convert objects to each other.

So if you are solicitous about how to use these service in the presentation layer, take a look again! I'm using MVC4 in UI, here is what I've done in the controller :

 

    public class NewsController : BaseController
    {
        private readonly INewsService _newsService;
        public NewsController(ICookieStorageService cookieStorageService, INewsService newsService)
            : base(cookieStorageService)
        {
            _newsService = newsService;
        }
       public ActionResult Create()
        {
            return View("Create");
        }
        [HttpPost]
        public ActionResult Create(NewsViewModel newsViewModel)
        {
            var createNewsRequest = new CreateNewsRequest(newsViewModel);
            if (ModelState.IsValid)
            {
                _newsService.CreateNews(createNewsRequest);
                 return View("Create");
            }
            return View("Create");
        }
        public ActionResult Archive(int year, int month)
        {
            var request = new GetAllNewsRequest(year, month);
            var newses = _newsService.GetAllArchivedNewsByDate(request);
            return View("Archive", newses.PostViewModels);
        }
   }

 

As you can see in Archive ActionResult  I just used the second constructor of GetAllNewsRequest and also can use any constructor if I need! Thanks for reading this and have a good time...

comments powered by Disqus