Windsor 容器组件在第一个控制器操作时不可用

发布于 2024-09-19 19:50:03 字数 2809 浏览 6 评论 0原文

我正在使用 global.asax.cs 中的配置来注册组件,但看起来容器在第一个 http 请求(HomeController > Index 操作)时尚未初始化,并且它给了我一个“ObjectContext 实例有已被处置,不能再用于需要连接的操作。”错误。

我找不到解决方案,这让我发疯!

我的 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...]
}

在第一个 http 请求时抛出异常的控制器:

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

}

存储库/接口:

通用接口:

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

通用存储库:

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

基于通用存储库的接口课程:

public interface ICourseRepository : IRepository<Course>
{
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遗失的美好 2024-09-26 19:50:23

我找到了一种方法来至少暂时解决这个问题。因为问题发生在第一个请求上,所以我刚刚在控制器中添加了另一个操作并将索引操作重定向到它。可能不是最好的解决方案,但不能在这个问题上花更多时间!

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

}

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

}
不念旧人 2024-09-26 19:50:19

如果您使用工作单元模式,您将解决您的问题

查看这篇文章工作单元模式,非常有用

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

Check this post Unit Of Work Pattern, is very usefull

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文