Ninject WebAPI由于已经处理了DbContext,因此无法完成操作

Joh*_*rer 10 entity-framework ninject repository asp.net-web-api

所以我使用的建议与属性和过滤器一个简单的存储库模式在这里,因为我使用的是Ninject.Web.WebApi-RC从NuGet包.

这适用于第一个请求,但由于我有我DbContext的请求范围,因此它会在所有后续请求中处理.

这是我的属性:

public class CommunicationKeyValidationAttribute : FilterAttribute
{
}
Run Code Online (Sandbox Code Playgroud)

这是我的过滤器:

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

这是我的存储库:

public class Repository : IRepository
{
    public Repository(MyDbContext dbContext)
    {
        this.dbContext = dbContext;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的Ninject绑定:

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

我的控制器看起来像这样:

public class HomeController 
{
    [CommunicationKeyValidation]
    public ActionResult Index()
    {
        // do stuff
    }
Run Code Online (Sandbox Code Playgroud)

这里的问题CommunicationKeyValidationFilter是只在第一个请求上调用构造函数.有没有办法,我可以在每次尝试解析过滤器时导致ninject构造此过滤器?

Rem*_*oor 16

过滤器由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();
Run Code Online (Sandbox Code Playgroud)