嗨,我是存储库模式的新手。我想就我所采用的方法提供反馈。
要求:为当前登录的用户构建菜单。
我的解决方案:
public interface IApplicationHelperService
{
List<Menu> GetMenuForRoles();
}
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();
}
}
public interface ICommonService
{
IUser CurrentUser { get; }
string ApplicationName { get; }
}
在类上实现ICommonService,我使用上下文获取当前用户,换句话说,我的服务层不了解HttpContext,因为将来有可能将其用于另一种类型的应用程序。因此,通过这种方式,我可以对所有应用程序由当前用户进行不同的处理,但是我的服务层不会介意。
因此,您应该提供的反馈是,将这种通用服务注入(inject)所有服务的方法是一种很好的方法,还是有另一种方法(我问的原因)是在以后的阶段中,我需要当前用户的出于审计目的或出于任何原因的详细信息。
希望这对某人有意义。 :-)
最佳答案
我们正在使用类似的方法。区别在于,我们没有将CommonService对象注入(inject)每个服务中。
我们正在使用WCF,并且为OperationContext写了一个扩展来存储用户名等。可以使用静态方法调用来访问此扩展中定义的属性。与CommonService实现相比,它具有优势。由于您使用的是IOC,因此没有直接方法可以在每个服务调用中将参数传递给CommonService。例如,如果要通过WCF调用发送用户名,则需要在每个构造函数中设置CurrentUser的值。
我不知道您是否打算使用WCF。但关键是:如果需要将变量传递给CommonService,则最终将在每个构造函数中填充此值。如果您不打算传递变量,则可以为您的服务创建一个基类,并强制开发人员使用该基类。
另外,您应将CommonService的生命周期管理器设置为UnityPerResolveLifeTimeManager,以免在每个构造函数中创建新实例。否则,您可能最终在每个Service中拥有不同的实例。