2

我有一个使用 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、存储库和实体框架,所以请不要觉得你在说低调对我来说,如果我似乎打破了一些非常基本的东西。

4

1 回答 1

1

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

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

于 2011-04-25T20:36:40.383 回答