Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository pattern for common items

Hi there i am new to the repository pattern. I would like to have feedback on the approach i am following.

Requirement : Build the menu for the user that is currently logged in.

My Solution :

  1. I created a Service, that will be called by the controller to get the menu items.

    public interface IApplicationHelperService
    {
        List<Menu> GetMenuForRoles();
    }
    
  2. The implementation for the service

    public class ApplicationHelperService : IApplicationHelperService
    {
        private readonly IMenuRepository _menuRepository; //this fecthes the entire menu from the datastore
        private readonly ICommonService _commonService; //this is a Service that contained common items eg. UserDetails, ApplicationName etc.
    
        public ApplicationHelperService(IMenuRepository menuRepository,ICommonService commonService)
        {
            this._menuRepository = menuRepository;
            this._commonService = commonService;
         }
    
         public List<Menu> ApplicationMenu
         {
            get
            {
               return _menuRepository.GetMenu(_commonService.ApplicationName);
            }
         }
    
         List<Menu> IApplicationHelperService.GetMenuForRoles()
         {
             return ApplicationMenu.Where(p => p.ParentID == null &&      p.IsInRole(_commonService.CurrentUser.Roles)).OrderBy(p => p.MenuOrder).ToList();
         }
    
    }
    
  3. Then the CommonService (used for common items needed in the Services eg. CurrentUser

    public interface ICommonService
    {
         IUser CurrentUser { get; }
         string ApplicationName { get; }
    }
    

On the class the implements the ICommonService, i get the current user using the context, in other words my service layer does not know about the HttpContext, since there is a possibility that this might by used for another type of application in the future. So this way i can handle by Current User differently for all applications, but my Service Layer will not mind.

So what you should give feedback on is, is this approach to inject this kind of common service into all services a good approach or is there another way of doing this, the reason i ask, is at a later stage i will need the current user's details for auditing purposes or whatever reason presents itself.

Hope this makes sense to someone. :-)

like image 695
Captain0 Avatar asked Nov 14 '22 00:11

Captain0


1 Answers

We are using a similar approach. The difference is that, we do not have a CommonService object injected into each service.

We are using WCF and we have written an extension to OperationContext to store Username etc. The properties defined in this extension can be accessed using static method calls. It has an advantage over CommonService implementation; since you are employing IOC, there is not direct way to pass parameters into CommonService in each service call. For instance, if you are sending the username on the WCF calls, you need to set the value of CurrentUser in each constructor.

I do not know whether you are planning to use WCF; but the point is that: if you need to pass variables to your CommonService, you will endup with populating this values inside each constructor. If you are not planning to pass variables, then you can just create a base class for your services and force the developers to use this base class.

Also, you should set the lifetime manager of CommonService as UnityPerResolveLifeTimeManager, in order not to create a new instance in each constructor.Otherwise, you may endup with having different instances in each Service.

like image 73
daryal Avatar answered Dec 09 '22 08:12

daryal