所以我正在使用一个简单的仓库模式与属性和过滤器建议
here,因为我正在使用来自NuGet的Ninject.Web.WebApi-RC包.
这适用于第一个请求,但是由于我的DbContext在请求范围内,因此它会处理所有后续请求.
这是我的属性:
- public class CommunicationKeyValidationAttribute : FilterAttribute
- {
- }
这是我的过滤器
- public class CommunicationKeyValidationFilter : AbstractActionFilter
- {
- public CommunicationKeyValidationFilter(IRepository repository)
- {
- this.repository = repository;
- }
- public override void OnActionExecuting(HttpActionContext actionContext)
- {
- // do stuff
- }
- }
这是我的存储库:
- public class Repository : IRepository
- {
- public Repository(MyDbContext dbContext)
- {
- this.dbContext = dbContext;
- }
- }
这是我的Ninject绑定:
- this.Kernel.Bind<MyDbContext>().ToSelf().InRequestScope();
- this.Kernel.Bind<IRepository>().To<Repository>().InRequestScope();
- this.Kernel.BindHttpFilter<CommunicationKeyValidationFilter>(FilterScope.Action)
- .WhenActionMethodHas<CommunicationKeyValidationAttribute>()
- .InRequestScope();
我的控制器如下所示:
- public class HomeController
- {
- [CommunicationKeyValidation]
- public ActionResult Index()
- {
- // do stuff
- }
这里的问题是CommunicationKeyValidationFilter上的构造函数只在第一个请求中被调用.有没有办法,我可以使ninject在每次尝试解析过滤器时构造此过滤器?
解决方法
过滤器被WebApi高速缓存.它们应该处于临时范围,以便WebApi可以管理生命周期.由于长生命周期,您不能有任何具有较短生命周期的依赖关系.
您可以做的是在执行过滤器期间创建存储库.为此,最好使用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();