【问题标题】:Ninject PerRequest injectionNinject PerRequest 注入
【发布时间】:2011-04-24 01:34:53
【问题描述】:

我有一个使用 Ninject.Web.Mvc2 和存储库模式(基于实体框架模型构建)的 MVC 2.0 应用程序。我正在尝试创建一个仅在请求期间存在的新 ObjectContext。我正在尝试通过以下方式完成此操作:

protected override IKernel CreateKernel(){
    var kernel = new StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());
    return kernel;
}

    protected override void OnApplicationStarted()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
    }

然后我没有足够的想法来保持这个通用性,所以我开始在 BeginRequest 中工作:

    protected void Application_BeginRequest()
    {
         string EntityConnectionString = ConfigurationManager.ConnectionStrings["Entities"].ConnectionString;
         HttpContext.Current.Items.Add(_PerRequestContextObjectKey, new EntityFrameworkContextWrapper(EntityConnectionString));
         this.Kernel.Bind<IUserRepository>().To<UserRepository>().WithConstructorArgument("ContextWrapper", HttpContext.Current.Items[_PerRequestContextObjectKey]);
    }

Wrapper 类只是一个通用对象,用于在请求结束时包含我想要杀死的任何内容。在这种特定情况下,我使用它来创建我的新 ObjectContext 并实现 IDisposable,因此我可以执行以下操作:

    protected void Application_EndRequest()
    {
        foreach (var Item in HttpContext.Current.Items)
        {
            if (Item.GetType() == typeof(IPerRequestLifetimeObjectWrapper))
            {
                (Item as IPerRequestLifetimeObjectWrapper).Dispose();
            }
        }
    }

我确信这不是最漂亮的方法,但在这一点上,我正努力开始行动,因为我花了很多时间“学习”所有这些东西。

然后像这样注入我的控制器:

public class AdminUserController : Controller
{
    // Mark for Ninject
    [Inject]  public IUserRepository _userRepo { get; set; }

    public ViewResult Index( )
    {
        return View(_userRepo.Get);
    }

    public ViewResult Edit(Guid UserUID)
    {
        return View(_userRepo.GetById(UserUID));
    }
}

我的存储库也被注入:

    [Inject]
    public UserRepository(EntityFrameworkContextWrapper ContextWrapper )  
        // Mark for Ninject Dependency Injection 
        // Must receive Wrapper that contains active ObjectContext
    {
        _db = ContextWrapper.Entities;  //Not actually named this, just easier for typing right now
    }

当我的控制器第一次调用我的 UserRepository 对象中的 Get 方法时,它的效果很好。如果我点击刷新(或者我猜也是回发),_db 为空。当我尝试单步调试调试器时,我发现在调用 Application_BeginRequest() 之前调用了 Controller Index() 方法。我以为我对“管道”有所了解(我习惯于从 WebForms 调用页面生命周期),但现在我有点迷失了。有人可以详细说明我的大脑在哪里交叉了一些电线吗?就像我说的,这可能不是最漂亮的方法,但我只有大约一个半星期的时间来学习 MVC、DI 与 Ninject、存储库和实体框架,所以请不要觉得你在说低调如果看起来我破坏了一些非常基本的东西,对我来说。

【问题讨论】:

  • 您不应该在 BeginRequest 中使用 Binding。查看示例并使用模块来容纳它们,或者每个 HttpApplication 至少执行一次

标签: asp.net-mvc-2 pipeline ninject-2


【解决方案1】:

您为什么不简单地使用 InRequestScope?您所做的是为每个请求添加一个新绑定。这将导致严重的问题。 见https://github.com/ninject/ninject.web.mvc/wiki/Unit-of-work-pattern-with-nhibernate

它是 NHilbernate,但你可以用 EntityFramework 做同样的事情

【讨论】:

  • 我对这一切还是很陌生,所以我不知道 InRequestScope。我一定会看的。从我在网上看到的一目了然,这正是我所需要的。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
  • 2017-05-28
相关资源
最近更新 更多