2015-11-02 50 views
0

我有一個購物車服務IShoppingCartService是與Ninject定義爲InRequestScope噴射需求範圍的對象爲MVC ActionFilterAttribute

this.Bind<IShoppingCartService>().To<ShoppingCartService>().InRequestScope(); 

它加載用戶的購物車,並在內部對其進行緩存。一旦請求結束,服務對象就會消失。

我需要訪問ActionFilter內的購物車,所以我使用了[Inject]屬性。

public class MyActionFilterAttribute : ActionFilterAttribute 
{ 
    [Inject] 
    public IShoppingCartService ShoppingCartService 
    { 
     get; set; 
    } 
} 

然後我就可以像這樣

public override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
     var cart = ShoppingCartService.ShoppingCart; 
     ... 
} 

使用它在行動過濾器現在對於怪異的一部分。這一直工作一年或更長時間 - 然後突然(最近升級Ninject和MVC後)我注意到購物車正在緩存(即不是InRequestScope)。

在進一步的研究中,我看到ActionFilters是單身人士(我驗證了這一點,因爲構造函數只被調用過一次)。所以一旦購物車的一個實例被加載,它就永遠被鎖定。

所以我的問題是 - 這究竟是如何工作的? Ninject或MVC最近有什麼變化可以讓它在之前工作。

我修復,現在是做到以下幾點:

public IShoppingCartService ShoppingCartService 
{ 
    get 
    { 
     var scs = (IShoppingCartService) DependencyResolver.Current.GetService(typeof(IShoppingCartService)); 
     return scs; 
    } 
} 

我真的很困惑,雖然爲如何以往任何時候都可以工作 - 它肯定沒有。我應該做些什麼呢?

回答

1

也許而過濾器屬性只實例化一次,屬性是[Injected] - 每次頁面擊中。但讓我們期待:)

2010年在Ninject.MVCx(x = 3,5,..)實施了一個「新」方法,以便如何將動作注入動作過濾器。它不需要依賴屬性,並且它支持構造函數注入。下面是它的樣子:

公平的警告:我通常不會做asp.net開發,我沒有去嘗試,如果下面不改變對IActionFilter的生命週期東西,所以你「將不得不嘗試一下自己,如果你這樣做,請提供反饋)

public class MyActionFilter : IActionFilter 
{ 
    private readonly IShoppingCartService shoppingCartService; 

    public MyActionFilter(IShoppingCartService shoppingCartService) 
    { 
     this.shoppingCartService = shoppingCartService; 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     var cart = ShoppingCartService.ShoppingCart; 
     ... 
    } 
} 

然後過濾器需要通過特殊的方法BindFilter的約束:

this.BindFilter<MyActionFilter>(FilterScope.Action, 0) 
    .WhenControllerTypeIs<YourController>(); 

將適用它到YourController的所有行動。

還有可以應用濾鏡其他目標來,通過使用:

// Is applied to all actions of controllers which have the FooAttribute 
this.BindFilter<MyActionFilter>(FilterScope.Action, 0) 
    .WhenControllerHas<FooAttribute>(); 

// Is applied to all actions which have the FooAttribute 
this.BindFilter<MyActionFilter>(FilterScope.Action, 0) 
    .WhenActionHas<FooAttribute>(); 

// Is applied to all actions named Index 
this.BindFilter<MyActionFilter>(FilterScope.Action, 0) 
    .When((controllerContext, actionDescriptor) => 
     actionDescriptor.ActionName == "Index"); 

有對一些更多的信息,可以在一個偉大的文章Remo Gloor發現:Official Ninject MVC extension gets support for MVC3(章依賴注入過濾器