namespace Framework.IoC
{
#region Using directives
using System;
using System.Collections.Generic;
using System.Configuration;
using Properties;
#endregion
/// <summary>
/// The IoC Container static class provides inversion of control and service lookup functionality.
/// </summary>
public static class Container
{
/// <summary>
/// static readonly dictionary to store the instances.
/// </summary>
private static readonly IDictionary<string, object> factories = new Dictionary<string, object>();
/// <summary>
/// Configuration Section name
/// </summary>
private const string sectionName = "ioc";
/// <summary>
/// some object to lock when filling the dictionary to rnsure thread safety.
/// </summary>
private static readonly object iocLock = new object();
/// <summary>
/// resolve a component of the specified <typeparamref name="T"/> type.
/// </summary>
/// <typeparam name="T">The type of component to resolve or build.</typeparam>
/// <returns>An instance of <typeparamref name="T"/>.</returns>
public static T Resolve<T>() where T : class
{
T factory;
var key = typeof(T).FullName;
object factoryItem;
// See if the factory is in the cache
if (factories.TryGetValue(key, out factoryItem))
{
// It was there, so retrieve it from the cache.
factory = factoryItem as T;
}
else
{
// not in dictionary, let's create the factory.
// Get the entityMappingsConfiguration config section
var dictionary = (Dictionary<string, string>)ConfigurationManager.GetSection(sectionName);
string typeName;
if (!dictionary.TryGetValue(key, out typeName))
throw new ArgumentOutOfRangeException(string.Format(Resources.key_not_found, key));
// Get the type to be created using reflection
var factoryType = Type.GetType(typeName);
// if factoryType is null throw.
if (factoryType == null)
throw new NullReferenceException(typeName);
// Create the factory using reflection
factory = Activator.CreateInstance(factoryType) as T;
lock (iocLock)
{
// Put the newly created factory in the cache
factories[key] = factory;
}
}
// if null than throw Exception.
if (factory == default(T))
throw new Exception(string.Format(Resources.cannot_instanciate, key));
return factory;
}
}
}