using System;
using System.Collections.Generic;
using System.Threading;
namespace AzureCoding.Samples.ServiceLocator
{
/// <summary>
/// A simple, straightforward Service Locator Implementation
/// </summary>
public class ServiceContainer
{
private readonly Dictionary<Type,Object> _Services=new Dictionary<Type, object>();
private readonly ReaderWriterLockSlim _ServicesLock = new ReaderWriterLockSlim();
private static readonly ServiceContainer _Container = new ServiceContainer();
public static ServiceContainer Instance
{
get { return _Container; }
}
private ServiceContainer()
{
}
private void AddService<TService>(TService instance)
{
_ServicesLock.EnterUpgradeableReadLock();
try
{
if (!_Services.ContainsKey(typeof(TService)))
{
_ServicesLock.EnterWriteLock();
try
{
_Services[typeof(TService)] = instance;
}
finally
{
_ServicesLock.ExitWriteLock();
}
}
}
finally
{
_ServicesLock.ExitUpgradeableReadLock();
}
}
private TService RetrieveService<TService>()
{
TService retVal;
_ServicesLock.EnterReadLock();
try
{
retVal = (TService)_Services[typeof(TService)];
}
catch (Exception)
{
throw new Exception(String.Format("Service Type {0} not registered with container.", typeof(TService).Name));
}
finally
{
_ServicesLock.ExitReadLock();
}
return retVal;
}
public static void RegisterService<TService>(TService instance)
{
_Container.AddService(instance);
}
public static TService GetService<TService>()
{
return _Container.RetrieveService<TService>();
}
public static void ClearServices()
{
_Container.Reset();
}
private void Reset()
{
_ServicesLock.EnterWriteLock();
try
{
_Services.Clear();
}
finally
{
_ServicesLock.ExitWriteLock();
}
}
}
}