Skip to content

Instantly share code, notes, and snippets.

@haf
Created May 8, 2012 22:45
Show Gist options
  • Save haf/2640092 to your computer and use it in GitHub Desktop.
Save haf/2640092 to your computer and use it in GitHub Desktop.
BackgroundFactoryMethod
/// <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