我将 NInject 与 NInject.Web.Mvc 一起使用。
首先,我创建了一个简单的测试项目,我希望IPostRepository
在同一个 Web 请求期间在控制器和自定义模型绑定器之间共享一个实例。在我的真实项目中,我需要这个,因为我遇到了IEntityChangeTracker
问题,我实际上有两个存储库访问同一个对象图。所以为了让我的测试项目简单,我只是想共享一个虚拟存储库。
我遇到的问题是它适用于第一个请求,仅此而已。相关代码如下。
NInject 模块:
public class PostRepositoryModule : NinjectModule
{
public override void Load()
{
this.Bind<IPostRepository>().To<PostRepository>().InRequestScope();
}
}
自定义模型绑定器:
public class CustomModelBinder : DefaultModelBinder
{
[Inject]
public IPostRepository repository { get; set; }
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
repository.Add("Model binder...");
return base.BindModel(controllerContext, bindingContext);
}
}
public class HomeController : Controller
{
private IPostRepository repository;
public HomeController(IPostRepository repository)
{
this.repository = repository;
}
public ActionResult Index(string whatever)
{
repository.Add("Action...");
return View(repository.GetList());
}
}
全球.asax:
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(string), kernel.Get<CustomModelBinder>());
}
这样做实际上是创建 2 个单独的实例IPostRepository
而不是共享实例。关于将依赖项注入我的模型绑定器,我在这里缺少一些东西。我上面的代码基于NInject.Web.Mvc wiki中描述的第一种设置方法,但我都尝试过。
当我确实使用第二种方法时,IPostRepository
只会为第一个 Web 请求共享,之后默认不共享实例。然而,当我真正开始工作时,我使用的是默认值DependencyResolver
,因为我一生都无法弄清楚如何对 NInject 做同样的事情(因为内核隐藏在 NInjectMVC3 类中)。我是这样做的:
ModelBinders.Binders.Add(typeof(string),
DependencyResolver.Current.GetService<CustomModelBinder>());
我怀疑这只是第一次起作用的原因是因为这不是通过 NInject 解决它,所以生命周期实际上是由 MVC 直接处理的(尽管这意味着我不知道它是如何解决依赖关系的)。
那么我该如何正确注册我的模型绑定器并让 NInject 注入依赖项呢?