10

因此,由于我使用的是 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 每次尝试解析过滤器时都构造这个过滤器?

4

1 回答 1

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();
于 2013-03-15T15:46:55.287 回答