2014-01-18 45 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