Skip to content

Instantly share code, notes, and snippets.

@amiry-jd
Last active December 17, 2015 12:29
Show Gist options
  • Save amiry-jd/5610025 to your computer and use it in GitHub Desktop.
Save amiry-jd/5610025 to your computer and use it in GitHub Desktop.
Yet another implementation of ASP.NET Web Api IDependencyResolver and IDependencyScope, using SimpleInjector, for Self Hosted Environments
public class SiWebApiDependencyResolver : IDependencyResolver {
private readonly Container _container;
private readonly IDependencyScope _rootScope;
private bool _disposed;
public SiWebApiDependencyResolver(Container container) {
if (container == null)
throw new ArgumentNullException("container");
_container = container;
_rootScope = new SiWebApiDependencyScope(container);
}
public Container Container {
get { return _container; }
}
public object GetService(Type serviceType) {
return _rootScope.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType) {
return _rootScope.GetServices(serviceType);
}
public IDependencyScope BeginScope() {
return new SiWebApiDependencyScope(_container);
}
~SiWebApiDependencyResolver() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) {
if (_disposed)
return;
if (disposing && _rootScope != null)
_rootScope.Dispose();
_disposed = true;
}
}
public class SiWebApiDependencyScope : IDependencyScope {
private bool _disposed;
private readonly int _initialThreadId;
private readonly Container _container;
private readonly Queue<IDisposable> _disposables;
private LifetimeScope _lifetimeScope;
public SiWebApiDependencyScope(Container container) {
if (container == null)
throw new ArgumentNullException("container");
_container = container;
_lifetimeScope = container.BeginLifetimeScope();
_disposables = new Queue<IDisposable>();
_initialThreadId = Thread.CurrentThread.ManagedThreadId;
}
public Container Container {
get { return _container; }
}
public LifetimeScope LifetimeScope {
get { return _lifetimeScope; }
}
public object GetService(Type serviceType) {
try {
var service = _container.GetInstance(serviceType);
if (service is IDisposable)
_disposables.Enqueue(service as IDisposable);
return service;
} catch {
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType) {
try {
var services = _container.GetAllInstances(serviceType).ToList();
foreach (var service in services.OfType<IDisposable>())
_disposables.Enqueue(service);
return services;
} catch {
return Enumerable.Empty<object>();
}
}
~SiWebApiDependencyScope() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) {
if (_disposed)
return;
if (disposing && _lifetimeScope != null) {
if (_initialThreadId == Thread.CurrentThread.ManagedThreadId) {
_disposables.Clear();
_lifetimeScope.Dispose();
} else {
while (_disposables.Count > 0)
_disposables.Dequeue().Dispose();
}
_lifetimeScope = null;
}
_disposed = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment