- Passing Windsor Castle Injected Dependency to a Parallel Thread - Dispose() problem
- public class Repository : IRepository {
- private MyContext _dc; // MyContext inherits from ObjectContext
- public Repository() {
- _dc = new MyContext();
- }
- public void Dispose() {;
- _dc.Dispose();
- }
- }
- public class WindsorControllerFactory : DefaultControllerFactory {
- IWindsorContainer _container;
- public WindsorControllerFactory(IWindsorContainer container) {
- _container = container;
- // Do stuff to register all controller types
- }
- protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
- // Do stuff to resolve dependency
- }
- public override void ReleaseController(IController controller) {
- // by releasing the container, Windsor will call my Dispose() method on my repository
- _container.Release(controller);
- base.ReleaseController(controller);
- }
- }
- public class HomeController : Controller {
- IRepository _repository;
- public HomeController(IRepository repository) {
- _repository = repository;
- }
- public ActionResult Index() {
- var c = _repository.GetCompany(34);
- new Task(() => {
- System.Threading.Thread.Sleep(2000); // simulate long running task
- // will throw an error because my repository (and therefore, ObjectContext) will have been disposed.
- var c2 = _repository.GetCompany(35);
- }).Start();
- return Content(c.Name, "text/plain");
- }
- }
- protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
- {
- IController controller;
- // Do stuff to resolve dependency
- if(controller is LongTaskController)
- {
- ((LongTaskController) controller).CompleteLongTask += (sender, args) => _container.Release(controller);
- }
- }
- public override void ReleaseController(IController controller)
- {
- // by releasing the container, Windsor will call my Dispose() method on my repository
- if(!(controller is LongTaskController && ((LongTaskController)controller).HasLongTask)
- {
- _container.Release(controller);
- }
- base.ReleaseController(controller);
- }
- public class HomeController : LongTaskController
- {
- private readonly IRepository _repository;
- public HomeController(IRepository repository)
- {
- _repository = repository;
- }
- public ActionResult Index()
- {
- var c = _repository.GetCompany(34);
- DoLongTask(() =>
- {
- Thread.Sleep(200);
- var c2 = _repository.GetCompany(35);
- });
- return Content(c.Name, "text/plain");
- }
- }
- public abstract class LongTaskController: Controller,IHasLongTask
- {
- private bool _hasLongTask;
- public bool HasLongTask { get { return _hasLongTask; } }
- public event EventHandler CompleteLongTask;
- void IHasLongTask.DoLongTask(Action action) { DoLongTask(action); }
- protected void DoLongTask(Action action)
- {
- _hasLongTask = true;
- if (CompleteLongTask == null)
- {
- throw new NullReferenceException("Controller.CompleteLongTask cannot be null when Controller does a long running task.");
- action += () => CompleteLongTask(this, EventArgs.Empty);
- }
- new Task(action).Start();
- }
- }
- public interface IHasLongTask
- {
- bool HasLongTask { get; }
- void DoLongTask(Action action);
- event EventHandler CompleteLongTask;
- }