1

I'm using a configuration within the global.asax.cs to register the components but it looks the container hasn't been initialized yet at the first http request (HomeController > Index action) and it gives me a "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection." error.

I can't find a solution for this and is driving me mad!

Extract of my global.asax.cs:

protected void Application_Start()
{
    InitializeContainer();
    InitializeDatabase();
    RegisterRoutes(RouteTable.Routes);
}

private void InitializeContainer()
{
    _container = new WindsorContainer();

    ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container));

    // Register context manager.
    _container.Register(
        Component.For<IContextManager>()
        .ImplementedBy<CoursesContextManager>()
        .LifeStyle.Singleton
        .Parameters(
    Parameter.ForKey("connectionString").Eq(ConfigurationManager.ConnectionStrings["CoursesConnection"].ConnectionString)   
        )
    );
    // Register specifc repository implementations (can we do this more generic?)
    _container.Register(
        Component.For<ICourseRepository>()
        .ImplementedBy<CourseRepository>()
        .LifeStyle.Singleton
    );

    [...other interfaces and controllers registered...]
}

Controller where the exception is thrown at first http request:

public class HomeController : Controller
{
    private ICourseRepository _courseRepository;

    public HomeController(ICourseRepository courseRepository)
    {
        _courseRepository = courseRepository;
    }

    public ActionResult Index()
    {
        var courses = _courseRepository.Find(); //here is where it fails
        return View(courses);
    }

}

Repository/interfaces:

Generic interface:

public interface IRepository<T>
{
    IQueryable<T> Find();
}

Generic repository:

public class MyRepository<T> : IRepository<T> where T : class
{
    private IContextManager _contextManager;
    private string _qualifiedEntitySetName;
    private string _keyName;

    protected ObjectContext CurrentObjectContext
    {
        get { return _contextManager.GetContext(); }
    }

    protected ObjectSet<T> ObjectSet
    {
        get { return CurrentObjectContext.CreateObjectSet<T>(); }
    }

    public MyRepository(IContextManager contextManager)
    {
        this._contextManager = contextManager;
        this._qualifiedEntitySetName = string.Format("{0}.{1}"
            , this.ObjectSet.EntitySet.EntityContainer.Name
            , this.ObjectSet.EntitySet.Name);
        this._keyName = this.ObjectSet.EntitySet.ElementType.KeyMembers.Single().Name;
    }

    public IQueryable<T> Find()
    {
        return ObjectSet;
    }
}

Interface course based on generic repository:

public interface ICourseRepository : IRepository<Course>
{
}
David Aleu
  • 3,922
  • 3
  • 27
  • 48
  • Added the controller with the line where it gives the error. – David Aleu Sep 17 '10 at 11:58
  • 1
    @tricate - Can you add the code for the Find method of the repository? I still don't think this is an IoC issue. – djdd87 Sep 17 '10 at 12:49
  • yes, sorry but I'm trying to simplify the question. Ignore the 3 top courses bit... the code I posted would return all the courses and it gives the same error. – David Aleu Sep 17 '10 at 15:28
  • I found a post that explains this issue more in detail: http://blog.alanta.nl/2009/07/castle-perwebrequestlifestyle-wont-work.html however, the solution doesn't seem to be efficient (besides I tried and it doesn't really solves the problem fully, the container can be accessed but the components not) – David Aleu Sep 17 '10 at 15:33

2 Answers2

0

if you use Unit Of Work pattern you will solve your problem

Check this post Unit Of Work Pattern, is very usefull

muek
  • 1,080
  • 2
  • 16
  • 36
0

I found a way to handle with this at least momentarily. Because the problem happens on the first request, I've just added another action in my controller and redirect the index action to it. Probably not the best solution but can't spend more time on this issue!

public class HomeController : Controller
{
    private ICourseRepository _courseRepository;

    public HomeController(ICourseRepository courseRepository)
    {
        _courseRepository = courseRepository;
    }

    public ActionResult Index() // Default action in the controller, first hit
    {
       return RedirectToAction("Home");
    }

    public ActionResult Home() //The repository is available here, no exception thrown
    {
        var courses = _courseRepository.Find(); //here is where it fails
        return View(courses);
    }

}
David Aleu
  • 3,922
  • 3
  • 27
  • 48