2013-03-11 9 views
10

Używam prostego wzorca repozytoriów z atrybutami i filtrami zgodnie z zaleceniami here, ponieważ korzystam z pakietu Ninject.Web.WebApi-RC od NuGet.Ninject WebAPI Nie można ukończyć operacji, ponieważ obiekt DbContext został usunięty.

To działa na pierwsze żądanie, ale ponieważ mam zakres DbContext w zakresie żądania, jest on usuwany we wszystkich kolejnych żądaniach.

Oto mój atrybut:

public class CommunicationKeyValidationAttribute : FilterAttribute 
{ 
} 

Oto mój filtr:

public class CommunicationKeyValidationFilter : AbstractActionFilter 
{ 
    public CommunicationKeyValidationFilter(IRepository repository) 
    { 
     this.repository = repository; 
    } 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     // do stuff 
    } 
} 

Oto mój repozytorium:

public class Repository : IRepository 
{ 
    public Repository(MyDbContext dbContext) 
    { 
     this.dbContext = dbContext; 
    } 
} 

Oto moje Wiązania Ninject:

this.Kernel.Bind<MyDbContext>().ToSelf().InRequestScope(); 
this.Kernel.Bind<IRepository>().To<Repository>().InRequestScope(); 
this.Kernel.BindHttpFilter<CommunicationKeyValidationFilter>(FilterScope.Action) 
     .WhenActionMethodHas<CommunicationKeyValidationAttribute>() 
     .InRequestScope(); 

Mój kontroler wygląda następująco:

public class HomeController 
{ 
    [CommunicationKeyValidation] 
    public ActionResult Index() 
    { 
     // do stuff 
    } 

Problem jest to, że konstruktor na CommunicationKeyValidationFilter jest tylko miano na pierwsze żądanie. Czy istnieje sposób, w jaki mogę spowodować, by ninject skonstruował ten filtr za każdym razem, gdy próbuje rozwiązać filtr?

+0

udało mi się powtórzenia błędu problemu: (? Bug), więc byłoby to błąd w Ninject które jest spowodowane przez funkcję w web.api powiedzieć . Wygląda na to, że Web.Api sama buforuje filtry: znalazłem to w [autofac web.api integration] (https://code.google.com/p/autofac/wiki/WebApiIntegration): "W przeciwieństwie do dostawcy filtru w MVC jeden w Web API nie pozwala ci określić, że instancje filtru nie powinny być buforowane, co oznacza, że ​​wszystkie ** atrybuty filtru w Web API są efektywnymi pojedynczymi instancjami istniejącymi przez cały okres istnienia aplikacji. ** " – nemesv

+0

Tak, Wierzę, że czytam ten sam artykuł. Zastanawiam się, czy ktokolwiek sobie z tym poradził, pisząc niestandardowego dostawcę filtru lub coś, co tworzy nowe wystąpienie podczas każdego żądania. –

+0

Interesująco, że Ninject udostępnia dwa filtry dostawców 'DefaultFilterProvider' oraz' NinjectFilterProvider' dla Web.API ... – nemesv

Odpowiedz

15

Filtry są buforowane przez WebApi. Powinny mieć zakres przejściowy, aby WebApi mógł zarządzać cyklem życia. Z powodu długiego cyklu życia nie można mieć zależności, która ma krótszy cykl życia.

To, co możesz zrobić, to stworzyć swoje repozytorium podczas wykonywania filtra. W tym celu najlepiej jest wstrzykiwać fabrykę pomocą NinjectFactoryExtension:

public class CommunicationKeyValidationFilter : AbstractActionFilter 
{ 
    public CommunicationKeyValidationFilter(IRepositoryFactory repositoryFactory) 
    { 
     this.repositoryFactory = repositoryFactory; 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var repository = this.repositoryFactory.CreateRepository(); 
    } 
} 

public interface IRepositoryFactory { IRepository CreateRepository(); } 
kernel.Bind<IRepositoryFactory>().ToFactory(); 
+1

Dzięki. To nie jest tak wygodne, jak użycie iniekcji konstruktora, ale rozwiązuje mój problem. –

+0

@Remo Czy to buforowanie filtrów specyficznych dla WebApi? Czy powinniśmy również używać fabryk do filtrów MVC? Dzięki za całą twoją pracę. – kenchilada

+0

Nie jest to specyficzne dla interfejsu WebAPI. Mvc robi to samo –

Powiązane problemy