2016-04-03 39 views
1

对于每一个页面请求初始化对象的状态,我需要从数据库中获得一些当前用户权限的数据,然后在逻辑 使用此信息几次(这是由几个对象的)的IoC - 在构造

我希望每次请求都从数据库中获取数据,并在需要时通过注入来重用它。

下面是做到这一点的最好方法吗?

1)这样定义

class ApplicationUser : IApplicationUserProvider 
{ 
    private UserPermissions _userPermissions; 
    ... 

    public ApplicationUser(IDatabase userService) 
    { 
     _userPermissions = userService.GetUserPermission(); // this would executed for every request once 
    } 

    UserRoles GetRoles() 
    { 
     return _userPermissions; 
    } 
} 

2物体)定义IOC像这样

var container1 = new Container(c => 
      { 
     c.For<IDatabase>().Use<Database>(); 
     c.For<IApplicationUser>().Use<ApplicationUser >(); 
     c.For<IApplicationLogic1>().Use<ApplicationLogic1>(); // this has IApplicationUser in ctor 
     c.For<IApplicationLogic2>().Use<ApplicationLogic2>(); // this has IApplicationUser in ctor 
      }); 

3)控制器将是

void PageController(IApplicationLogic1 l1) 
{ 
    l1.Process(); 
    l2.Process(); 
} 

回答

1

UserPermissions信息是运行时数据,并且如解释here,运行时数据不应该在对象图的构建期间注入或解决。

相反,调用userService.GetUserPermission()应该移出构造函数。例如通过使用Lazy<T>延迟呼叫:

class ApplicationUser : IApplicationUserProvider 
{ 
    private Lazy<UserPermissions> _userPermissions; 

    public ApplicationUser(IDatabase userService) { 
     _userPermissions = new Lazy<UserPermissions>(userService.GetUserPermission); 
    } 

    UserRoles GetRoles() { 
     return _userPermissions.Value.GetRoles(); 
    } 
} 

另一种选择是定义在IDatabase一个装饰将实现缓存:

public class PerRequestCacheDatabaseDecorator : IDatabase 
{ 
    private IDatabase _decoratee; 

    public PerRequestCacheDatabaseDecorator(IDatabase decoratee) { 
     _decoratee = decoratee; 
    } 

    public UserPermissions GetUserPermission() { 
     var items = HttpContext.Current.Items; 
     if (items["permissions"] == null) 
      items["permissions"] = _decoratee.GetUserPermission(); 
     return (UserPermissions)items["permissions"]; 
    } 
} 

通过包装PerRequestCacheDatabaseDecorator内真实的数据库,你可以简化ApplicationUser以下几点:

class ApplicationUser : IApplicationUserProvider 
{ 
    private IDatabase _userService; 

    public ApplicationUser(IDatabase userService) { 
     _userService = userService; 
    } 

    public UserRoles GetRoles() { 
     return _userService.GetUserPermission().GetRoles(); 
    } 
} 

现在无论是ApplicationUserDatabase类都关心这种性能优化,这是一件好事。装饰器允许我们插入此性能优化,而无需更改任何现有的类。

相关问题