所以我正在使用一个简单的仓库模式与属性和过滤器建议
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();