Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Jun 26th, 2012  |  syntax: None  |  size: 3.58 KB  |  hits: 13  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. Passing Windsor Castle Injected Dependency to a Parallel Thread - Dispose() problem
  2. public class Repository : IRepository {
  3.  
  4.     private MyContext _dc; // MyContext inherits from ObjectContext
  5.  
  6.     public Repository() {
  7.         _dc = new MyContext();
  8.     }
  9.  
  10.     public void Dispose() {;
  11.         _dc.Dispose();
  12.     }
  13. }
  14.        
  15. public class WindsorControllerFactory : DefaultControllerFactory {
  16.         IWindsorContainer _container;
  17.  
  18.         public WindsorControllerFactory(IWindsorContainer container) {
  19.             _container = container;
  20.             // Do stuff to register all controller types
  21.         }
  22.  
  23.         protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
  24.             // Do stuff to resolve dependency
  25.         }
  26.  
  27.         public override void ReleaseController(IController controller) {
  28.             // by releasing the container, Windsor will call my Dispose() method on my repository
  29.             _container.Release(controller);
  30.             base.ReleaseController(controller);
  31.         }
  32.     }
  33.        
  34. public class HomeController : Controller {
  35.  
  36.     IRepository _repository;
  37.  
  38.     public HomeController(IRepository repository) {
  39.         _repository = repository;
  40.     }
  41.  
  42.     public ActionResult Index() {
  43.         var c = _repository.GetCompany(34);
  44.  
  45.         new Task(() => {
  46.             System.Threading.Thread.Sleep(2000); // simulate long running task
  47.             // will throw an error because my repository (and therefore, ObjectContext) will have been disposed.
  48.             var c2 = _repository.GetCompany(35);
  49.         }).Start();
  50.  
  51.         return Content(c.Name, "text/plain");
  52.     }
  53. }
  54.        
  55. protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
  56.     {
  57.         IController controller;
  58.         // Do stuff to resolve dependency
  59.         if(controller is LongTaskController)
  60.         {
  61.             ((LongTaskController) controller).CompleteLongTask += (sender, args) => _container.Release(controller);
  62.         }
  63.     }
  64.  
  65.     public override void ReleaseController(IController controller)
  66.     {
  67.         // by releasing the container, Windsor will call my Dispose() method on my repository
  68.         if(!(controller is LongTaskController && ((LongTaskController)controller).HasLongTask)
  69.         {
  70.             _container.Release(controller);
  71.         }
  72.         base.ReleaseController(controller);
  73.     }
  74.        
  75. public class HomeController : LongTaskController
  76. {
  77.     private readonly IRepository _repository;
  78.     public HomeController(IRepository repository)
  79.     {
  80.         _repository = repository;
  81.     }
  82.     public ActionResult Index()
  83.     {
  84.         var c = _repository.GetCompany(34);
  85.         DoLongTask(() =>
  86.         {
  87.             Thread.Sleep(200);
  88.             var c2 = _repository.GetCompany(35);
  89.         });
  90.         return Content(c.Name, "text/plain");
  91.     }
  92. }
  93.        
  94. public abstract class LongTaskController: Controller,IHasLongTask
  95. {
  96.     private bool _hasLongTask;
  97.     public bool HasLongTask { get { return _hasLongTask; } }
  98.     public event EventHandler CompleteLongTask;
  99.     void IHasLongTask.DoLongTask(Action action) { DoLongTask(action); }
  100.     protected void DoLongTask(Action action)
  101.     {
  102.         _hasLongTask = true;
  103.         if (CompleteLongTask == null)
  104.         {
  105.             throw new NullReferenceException("Controller.CompleteLongTask cannot be null when Controller does a long running task.");
  106.             action += () => CompleteLongTask(this, EventArgs.Empty);
  107.         }
  108.         new Task(action).Start();
  109.     }
  110. }
  111. public interface IHasLongTask
  112. {
  113.     bool HasLongTask { get; }
  114.     void DoLongTask(Action action);
  115.     event EventHandler CompleteLongTask;
  116. }