0

I make custom authentication for my ASP.NET MVC project and I use EF 6.1.3 and Ninject.MVC 3.2.1. I use repositories and unit of work patterns. I want validate unique username at registration in my view model with custom ValidationAttribute. Sometimes my repository throw InvalidOperationException with description:

the operation cannot be completed because the dbcontext has been disposed.

This is my Ninject configuration:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<DbContext>().To<MyPortfolioDbContext>().InRequestScope();

    kernel.Bind(typeof(IDbRepository<>)).To(typeof(EfRepository<>));

    kernel.Bind<Func<IUnitOfWork>>().ToMethod(ctx => () => ctx.Kernel.Get<EfUnitOfWork>());
    kernel.Bind<IUnitOfWork>().To<EfUnitOfWork>();

    kernel.Bind<IAuthenticationManager>().To<AuthenticationManager>();

    kernel.Bind(k => k
        .From("MyPortfolio.Services.Authentication", "MyPortfolio.Services.Data")
        .SelectAllClasses()
        .BindDefaultInterface());
}

This is my ValidationAttribute:

public class RegistrationValidator : ValidationAttribute
{
    [Inject]
    public IDbRepository<User> Users { get; set; }

    public override bool IsValid(object value)
    {
        string username = (string)value;
        bool result = true;
        if (this.Users.FirstOrDefault(u => u.Username == username) != null)
        {
            result = false;
        }
        return result;
    }
}

And this is my repository:

public class EfRepository<T> : IDbRepository<T> where T : class, IAuditInfo, IDeletableEntity
{
    private IDbSet<T> dbSet;
    private DbContext context;

    public EfRepository(DbContext context)
    {
        if (context == null)
        {
            throw new ArgumentException("An instance of DbContext is required to use this repository.", nameof(context));
        }
        this.context = context;
        this.dbSet = this.context.Set<T>();
    }

    //another methods

    //the method that throw an exception
    public T FirstOrDefault(Expression<Func<T, bool>> filterExpression)
    {
        return this.dbSet.Where(x => !x.IsDeleted).FirstOrDefault(filterExpression);
    }

    //another methods
}

If you need another code of my project please tell me.

My hypothesis is that on injecting the repository into ValidationAttribute, Ninject used old dbContext. What is your opinion.

totkov
  • 123
  • 1
  • 6
  • Is there no obvious pattern to when this happens? My hypothesis is that `InRequestScope` and Attributes might not always mix well. See: https://stackoverflow.com/questions/29915192/property-injection-on-attributes – stephen.vakil Oct 05 '17 at 20:42
  • Yes, I understand, but repository and unit of work cannot working together without InRequestScope. What can I do in this case? – totkov Oct 05 '17 at 20:48
  • This check shouldn't be in an attribute anyway. It's more suitable in `IValidatableObject` although you'd still need some tricks to get the current context in there. – Gert Arnold Oct 05 '17 at 21:19

0 Answers0