2014-01-18 43 views
0

我有这个(简体)控制器设置:AuthorizeAttribute,构造函数和停止依赖注入

[CustomAuthorizeAttribute] 
public class MainController : Controller {} 

public class AccountController : MainController 
{ 
    private IService _iService; 

    public AccountController() 
    { 
     _service = DependencyFactory.Resolve<IService>(SessionManager.ServiceKey) 
    } 
    public AccountController(IService service) 
    { 
     _service = service; 
    } 
} 

而且CustomAuthorizeAttribute看起来像:

public CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     bool serviceKeyIsGood = CheckServiceKey(SessionManager.ServiceKey); 
     return serviceKeyIsGood; 
    } 
} 

的目标是只有账户控制器运行如果用户被认证,则由“良好”服务密钥的存在来定义。

我遇到的问题是,AccountController的构造函数在OnAuthorize运行之前运行,导致服务由于其服务密钥不良而被炸毁(按设计)。

管理这个最好的方法是什么?我想利用CustomAuthorizeAttribute的简单性,并且我必须避免重新设计我们的服务被实例化的方式。 (和依赖工厂是必要的,因为MVC抱怨现在有参数构造函数)。

回答

0

可以使用factorymethod,而不是服务本身的注射:

[CustomAuthorizeAttribute] 
public class MainController : Controller 

public class AccountController : MainController 
{ 
    private Func<IService> _serviceFactory; 

    public AccountController() 
    { 
     _serviceFactory= DependencyFactory.Resolve<Func<IService>>(SessionManager.ServiceKey) 
    } 
    public AccountController(Func<IService> serviceFactory) 
    { 
     _serviceFactory= serviceFactory; 
    } 
} 

和使用:获得服务:service = _serviceFactory()当你需要它。

PS:我建议你使用DI标准方法在MVC(控制器工厂或内部依赖解析器),以避免代码,_serviceFactory= DependencyFactory.Resolve<Func<IService>>(SessionManager.ServiceKey)

+0

我同意,DI是要走的路,但由于某种原因MVC不像有无参数的构造函数。 (我很难指出为什么...... Unity解决方案应该为我们解决这个问题,但这不是因为某种原因......这是一个单独的SO帖子)。使用无参数构造函数满足MVC的抱怨,同时使用DI构造函数可以进行测试。服务工厂是一个有趣的方法,但我们必须重新连接Unity容器。我们已经结束了吞咽由于安全原因而失败的解决方案错误,因为用户被踢出去了。 – DuncanMack

+0

如果在容器中注册T,Unity容器可以从框中解析Func