2011-04-24 4 views
2

J'ai une application MVC 2.0 en utilisant Ninject.Web.Mvc2 et un modèle de référentiel (construit sur un modèle de structure d'entité). J'essaye de créer un nouveau ObjectContext qui ne vivra que pendant la durée de la requête. Je tente d'accomplir ceci de la manière suivante:Ninject PerRequest injection

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

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

J'ai alors couru d'idées pour garder ce assez générique, donc je mis au travail dans le 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]); 
    } 

La classe wrapper est juste un objet générique pour inclure tout ce que je veux tuer à la fin de la requête. Dans ce cas précis, je l'utilise pour créer mon nouveau ObjectContext et aussi mettre en œuvre IDisposable afin que je puisse faire ce qui suit:

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

Je suis sûr que ce n'est pas la façon la plus jolie de le faire, mais à ce stade je J'essaie de bouger depuis que j'ai passé tellement de temps à "apprendre" tout ça.

Mon contrôleur est alors injecté comme ceci:

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)); 
    } 
} 

et mon dépôt s'injecte ainsi:

[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 
    } 

Quand mon contrôleur appelle la méthode Get dans mon UserRepository objet la première fois qu'il fonctionne génial. Si j'appuie sur refresh (ou si je pense aussi à la publication), _db est Null. Lorsque j'essaie de parcourir le débogueur, je trouve que la méthode Controller Index() est appelée avant l'appel d'Application_BeginRequest(). Je pensais avoir une compréhension du "pipeline" (j'ai l'habitude d'appeler les choses du cycle de vie de la page de WebForms), mais maintenant je suis un peu perdu. Quelqu'un peut-il élaborer sur où mon cerveau a des fils croisés? Comme je l'ai dit, ce n'est probablement pas la méthode la plus jolie, mais j'ai seulement eu environ une semaine et demie pour apprendre MVC, DI avec Ninject, Repository, et Entity Framework, donc ne vous sentez pas comme si vous parliez à moi si j'ai l'impression d'avoir cassé quelque chose de très basique. Pourquoi ne pas simplement utiliser InRequestScope?

+0

vous être 'Bind'ing shouldnt dans BeginRequest. Regardez un échantillon et utilisez un module pour les héberger ou au moins le faire une fois par HttpApplication –

Répondre

1

Ce que vous faites est d'ajouter une nouvelle liaison pour chaque demande. Cela conduira à de graves problèmes. Voir https://github.com/ninject/ninject.web.mvc/wiki/Unit-of-work-pattern-with-nhibernate

Il est NHilbernate mais vous pouvez faire la même chose avec EntityFramework

+0

Je suis encore assez nouveau à tout cela, donc je ne savais pas InRequestScope. Je vais certainement le regarder. D'après ce que je vois en ligne en un coup d'oeil, c'est exactement ce dont j'ai besoin. Merci! – SenseiHitokiri

Questions connexes