0

I've read this post DbContext has been disposed and autofac but I'm still getting the same error:

The operation cannot be completed because the DbContext has been disposed.

public class EFRepository : IRepository
{
    private EFDbContext context;

    public EFRepository(EFDbContext ctx)
    {
        context = ctx;
    }

    public TEntity FirstOrDefault<TEntity>(Expression<Func<TEntity, bool>> predicate, params Expression<Func<TEntity, object>>[] includes)
        where TEntity : class, IContextEntity
    {
        IQueryable<TEntity> query = includes.Aggregate<Expression<Func<TEntity, object>>, IQueryable<TEntity>>
                     (context.Set<TEntity>(), (current, expression) => current.Include(expression));            

        return query.FirstOrDefault(predicate);
    }
}

And in the Global.asax

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);

builder.Register<IRepository>(c => new EFRepository(new EFDbContext()));

ILifetimeScope container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Controller injection:

public class AccountController : Controller
{
    private readonly IRepository repository;
    private readonly IMembershipService membershipService;        

    public AccountController(IRepository repo, IMembershipService mmbrSvc)
    {
        repository = repo;
        membershipService = mmbrSvc;
    }
    [HttpPost]        
    public ActionResult Login(LoginViewModel viewModel)
    {
        if (!ModelState.IsValid)             
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);            

        string returnUrl = (string)TempData["ReturnUrl"];
        LoginDto accountDto = viewModel.GetLoginStatus(repository, membershipService, returnUrl);
        string accountDtoJson = JsonHelper.Serialize(accountDto);

        return Content(accountDtoJson, "application/json");
    }
}

Then in LoginViewModel:

public LoginDto GetLoginStatus(IRepository repo, IMembershipService mmbrSvc, string returnUrl)
    {
        repository = repo;
        membershipService = mmbrSvc;

        User user = repository.FirstOrDefault<User>(x => x.Username == Username, x => x.Membership);
    ............
    ............
    }
Community
  • 1
  • 1
Alexander C.
  • 1,171
  • 4
  • 16
  • 29

2 Answers2

2

You need to register the DbContext itself with AutoFac and give it the appropriate lifetime. InstancePerDependency is usually fine for repositories.

builder.RegisterType<EFDbContext>().AsSelf().InstancePerDependency();

Then, you don't need to give the repository registration an object, just register the type (remembering to specify the lifetime as well):

builder.Register<EFRepository>().As<IRepository>().InstancePerLifetimeScope();
Steve
  • 9,335
  • 10
  • 49
  • 81
  • Steve thanks for the suggestion, I tried builder.RegisterType().AsSelf().InstancePerDependency(); builder.RegisterType().As().InstancePerLifetimeScope(); But still getting the same error. – Alexander C. Feb 16 '16 at 03:10
  • @AlexanderC.how are you actually calling the repository method? – Steve Feb 16 '16 at 03:14
  • through controller dependency injection as well as dependency injection in other services builder.RegisterType().As().InstancePerLifetimeScope(); – Alexander C. Feb 16 '16 at 03:21
  • @AlexanderC.can you update your question with an example of your controller constructor and repository call. – Steve Feb 16 '16 at 03:23
  • @AlexanderC.maybe try changing your `DbContext` registration to `InstancePerLifetimeScope` as well. – Steve Feb 16 '16 at 03:37
  • I tried that as well and it didn't work. I decided not to inject DbContext into repository but wrap code inside public TEntity FirstOrDefault with Using(var context = new DbContext()) and it solved the problem. – Alexander C. Feb 17 '16 at 16:44
0

Use builder.RegisterType<EFDbContext>().AsSelf().SingleInstance();

Nellymandela
  • 109
  • 2
  • 11