Created
May 8, 2012 22:45
-
-
Save haf/2640092 to your computer and use it in GitHub Desktop.
BackgroundFactoryMethod
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Register the component in a background thread on the thread pool. | |
/// Exceptions from factory method are thrown when the component is resolved. | |
/// </summary> | |
/// <typeparam name="TService">Type of service your component IS or IMPLEMENTS.</typeparam> | |
/// <param name="serviceRegistration">Previous registration that is not committed to method of instantiation of component.</param> | |
/// <param name="factory">The actual factory method for creating the service</param> | |
/// <param name="beforeInitialization">An optional callback that is run on the thread pool thread before initialization happens. | |
/// You can use this let the thread pool thread block and wait on e.g. a synchronization primitive.</param> | |
/// <returns>A component registration for Windsor which contains everything Windsor needs to know to use | |
/// your factory method to create the component</returns> | |
public static ComponentRegistration<TService> UsingBackgroundFactoryMethod<TService>( | |
this ComponentRegistration<TService> serviceRegistration, | |
Func<TService> factory, | |
Action beforeInitialization = null) | |
where TService : class | |
{ | |
var waitForComp = new ManualResetEventSlim(false); | |
TService createdComponent = null; | |
Exception thrownException = null; | |
ThreadPool.QueueUserWorkItem(_ => | |
{ | |
_logger.Debug("thread pool before initialization executing"); | |
if (beforeInitialization != null) beforeInitialization(); | |
_logger.Debug("thread pool factory starting"); | |
try | |
{ | |
createdComponent = factory(); | |
_logger.Debug("thread pool factory done"); | |
} | |
catch (Exception e) | |
{ | |
_logger.Error("thread pool initialization exception", e); | |
thrownException = e; | |
} | |
waitForComp.Set(); | |
}); | |
var bus = new Lazy<TService>(() => | |
{ | |
_logger.Debug("waiting for initialization"); | |
waitForComp.Wait(); | |
if (thrownException != null) throw thrownException; | |
_logger.Debug("yielding created component"); | |
return createdComponent; | |
}); | |
return serviceRegistration.UsingFactoryMethod(() => bus.Value); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment