/// <summary>
/// Vytvori/vrati data context svazany s threadem nebo web requestem
/// </summary>
internal class DataContextFactory
{
#region Constants
/// <summary>
/// Vychozi klic pouzivany pro ukladani datakontextu
/// </summary>
private const string DefaultKey = "DATA_CONTEXT";
static readonly object Locker = new object();
#endregion
#region Public methods
/// <summary>
/// Vrati/vytvori data kontext svazany bud s threadem nebo web requestem
/// </summary>
/// <param name="key">klic pro ulozeni datakontextu</param>
/// <returns></returns>
public static DataContext GetScopedDataContext(string key)
{
lock (Locker)
{
if (HttpContext.Current != null)
return (DataContext)GetWebRequestScopedDataContextInternal(key);
return (DataContext)GetThreadScopedDataContextInternal(key);
}
}
/// <summary>
/// Vrati/vytvori data kontext svazany bud s threadem nebo web requestem
/// </summary>
/// <returns></returns>
public static DataContext GetScopedDataContext()
{
lock (Locker)
{
if (HttpContext.Current != null)
return (DataContext)GetWebRequestScopedDataContextInternal(null);
return (DataContext)GetThreadScopedDataContextInternal(null);
}
}
#endregion
#region Other methods
private static object GetThreadScopedDataContextInternal(string key)
{
if (key == null)
key = DefaultKey; //+ Thread.CurrentContext.ContextID;
var threadData = Thread.GetNamedDataSlot(key);
object context = null;
if (threadData != null)
context = Thread.GetData(threadData);
if (context == null)
{
context = CreateInstance();
if (context != null)
{
if (threadData == null)
threadData = Thread.AllocateNamedDataSlot(key);
Thread.SetData(threadData, context);
}
}
return context;
}
private static object CreateInstance()
{
DataContext context = null;
if (ConfigurationManager.GetSection("DataContextSection") != null)
{
var section = ConfigurationManager.GetSection("DataContextSection") as DataContextSection;
string connectionString = ConfigurationManager.ConnectionStrings[section.ConnectionString].ConnectionString;
string strType = section.Type;
string strAsm = section.Assembly;
ObjectHandle handle = Activator.CreateInstance(strAsm, strType);
if (handle != null)
{
object instance = handle.Unwrap();
if (instance != null)
{
Type type = instance.GetType();
if (connectionString == null)
context = (DataContext)Activator.CreateInstance(type);
else
context = (DataContext)Activator.CreateInstance(type, connectionString);
context.Log = Console.Out;
}
}
}
return context;
}
private static object GetWebRequestScopedDataContextInternal(string key)
{
object context;
if (HttpContext.Current == null)
{
context = CreateInstance();
return context;
}
// vytvori unikatni klic pro webrequest/context
if (key == null)
key = DefaultKey + HttpContext.Current.GetHashCode().ToString("x"); //+ Thread.CurrentContext.ContextID;
context = HttpContext.Current.Items[key];
if (context == null)
{
context = CreateInstance();
if (context != null)
HttpContext.Current.Items[key] = context;
}
return context;
}
#endregion
}