2015-11-06 1 views
0

J'ai un problème avec mon DbContext étant disposé lorsqu'il est utilisé dans mon CustomRoleProvider.DbContext a été éliminé dans RoleProvider personnalisé

J'ai installé mes fixations comme à:

kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope(); 
kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>)).InRequestScope(); 
kernel.Bind<MyContext>().ToSelf().InRequestScope(); 

J'utilise ce paquet NuGet Ninject.MVC5 v3.2.1.0 si Ninject est défini comme DependencyResolver primaire dans MVC. Par conséquent, pourquoi je suis en mesure de le faire DependencyResolver.Current.GetService<IGenericRepository<User>>().

Mais pour une raison quelconque, le contexte est éliminé.

J'ai essayé d'ajouter cette liaison à ma configuration:

kernel.Bind<MyContext>().ToSelf().WhenInjectedInto<RoleProvider>(); 

Mais cela ne fonctionne pas non plus. J'ai aussi essayé l'injection par injection de propriété

[Inject] 
public IGenericRepository<User> UserRepository { get; set; }; 

Mais que les résultats juste beaucoup de problèmes d'autres je ne suis pas en mesure de résoudre (encore). Dans la mesure où je peux dire à partir du message d'erreur, c'est ici que le problème est déclenché de

public abstract class BaseController : Controller 
{ 
    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     User.IsInRole("Admin"); // calls my CustomRoleProvider 
     base.OnActionExecuting(filterContext); 
    } 
} 

CustomRoleProvider mise en œuvre

public class CustomRoleProvider : RoleProvider 
{ 
    private readonly IGenericRepository<User> _userRepository; 

    public CustomRoleProvider() 
    { 
     // using Service Locator (anti pattern) 
     // cause MVC do not support DI in role providers (yet) 
     _userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>(); 
    } 

    public override bool IsUserInRole(string username, string roleName) 
    { 
     var user = _userRepository.AsQueryable().Where(x => x.Username == username && x.Role.Name == roleName); // dbcontext is here disposed... 
     return user.Any(); 
    } 

    public override string[] GetRolesForUser(string username) 
    { 
     var user = _userRepository.AsQueryable().Where(x => x.Username == username).Select(x => x.Role.Name); // dbcontext is here disposed... 
     return user.ToArray(); 
    } 

    // omitted... 
} 

IGenericRepository<T> mise en œuvre

public class GenericRepository<T> : IGenericRepository<T> 
    where T : class 
{ 
    private readonly MyContext _context; 
    private readonly DbSet<T> _dbSet; 

    public GenericRepository(MyContext context) 
    { 
     _context = context; 
     _dbSet = context.Set<T>(); 
    } 

    public IQueryable<T> AsQueryable() 
    { 
     return _dbSet.AsQueryable(); 
    } 
} 

Message d'erreur

[InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.] 
    System.Data.Entity.Internal.InternalContext.CheckContextNotDisposed() +34 
    System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +30 
    System.Data.Entity.Internal.InternalContext.Initialize() +21 
    System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +20 
    System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +79 
    System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() +21 
    System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() +64 
    System.Linq.Queryable.Where(IQueryable`1 source, Expression`1 predicate) +81 
    Presentation.Web.Providers.CustomRoleProvider.GetRolesForUser(String username) in ~\Application\Presentation.Web\Providers\CustomRoleProvider.cs:38 
    System.Web.Security.RolePrincipal.IsInRole(String role) +183 
    Presentation.Web.Controllers.BaseController.OnActionExecuting(ActionExecutingContext filterContext) in ~\Application\Presentation.Web\Controllers\BaseController.cs:27 
    ... 
+0

Vous semblez avoir éliminé tout code qui pourrait réellement nous aider à déterminer où le contexte est disposé! Pouvez-vous ajouter cela? – DavidG

+0

Quelles parties avez-vous? Vous avez en tête? Pour moi c'est tout le code qui est exécuté :) –

+0

Bien le contenu de la méthode 'IsUserInRole' pour un début. – DavidG

Répondre

2

donc apparemment le cycle de vie des RoleProvider i s toute la durée de vie de l'application MVC. (Ne me souviens pas où je l'ai lu)

doivent donc résoudre la dépendance dans chaque méthode :(

public class CustomRoleProvider : RoleProvider 
{ 
    public override bool IsUserInRole(string username, string roleName) 
    { 
     var userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>(); 
     var user = userRepository .AsQueryable().Where(x => x.Username == username && x.Role.Name == roleName); // dbcontext is here disposed... 
     return user.Any(); 
    } 

    public override string[] GetRolesForUser(string username) 
    { 
     var userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>(); 
     var user = userRepository .AsQueryable().Where(x => x.Username == username).Select(x => x.Role.Name); // dbcontext is here disposed... 
     return user.ToArray(); 
    } 

    // omitted... 
} 

Ne pas comprendre pourquoi cela ne fonctionne pas alors

kernel.Bind<MyContext>().ToSelf().WhenInjectedInto<RoleProvider>(); 

J'ai même essayé d'ajouter InSingletonScope

+0

Ah oui, c'est logique. – DavidG

+0

En ce qui concerne les raisons pour lesquelles la dernière ligne de code n'a pas aidé, votre fournisseur de rôle n'est créé qu'une seule fois, donc cela ne fait aucune différence. – DavidG

+0

Mais si le DbContext injecté dans un RoleProvider est un singleton, il ne doit pas être supprimé –