1: /// <summary>
2: /// Gets the data context.
3: /// </summary>
4: /// <typeparam name="T">Type of the data context to retrieve.</typeparam>
5: /// <returns>The data context.</returns>
6: public T GetDataContext<T>() where T : DataContext, new()
7: {
8: return GetDataContext<T>(null);
9: }
10:
11: /// <summary>
12: /// Gets the data context.
13: /// </summary>
14: /// <typeparam name="T">Type of the data context to retrieve.</typeparam>
15: /// <param name="contextKey">The context key to uniquely identify the context.</param>
16: /// <returns>The data context.</returns>
17: public T GetDataContext<T>(string contextKey) where T : DataContext, new()
18: {
19: var contextInfoKey = GetContextInfoKey<T>(contextKey);
20:
21: var dataContext = RetrieveDataContextFromCache<T>(contextInfoKey) ??
22: CreateAndCacheDataContext<T>(contextInfoKey);
23:
24: return dataContext;
25: }
26:
27:
28: /// <summary>
29: /// Application should access the datacontextcache in this manner, don't use the private variable
30: /// which is for local optimization only.
31: /// </summary>
32: protected Dictionary<string, DataContext> DataContextCache
33: {
34: get
35: {
36: if (dataContextCache == null)
37: {
38: if (IsWebApplication)
39: {
40: dataContextCache = IsWebApplication
41: ? (Dictionary<string, DataContext>)HttpContext.Current.Items[dataContextCacheKey]
42: : (Dictionary<string, DataContext>)CallContext.GetData(dataContextCacheKey);
43: }
44: if (dataContextCache == null)
45: {
46: dataContextCache = new Dictionary<string, DataContext>();
47: if (IsWebApplication)
48: HttpContext.Current.Items[dataContextCacheKey] = dataContextCache;
49: else
50: CallContext.SetData(dataContextCacheKey, dataContextCache);
51: }
52:
53: }
54: return dataContextCache;
55: }
56: }
57:
58:
59: /// <summary>
60: /// Retrieves the data context from cache.
61: /// </summary>
62: /// <typeparam name="T">Type of the data context.</typeparam>
63: /// <param name="contextInfoKey">The context info key.</param>
64: /// <returns>Data context if already cached.</returns>
65: protected T RetrieveDataContextFromCache<T>(string contextInfoKey)
66: {
67: object contextObject = DataContextCache[contextInfoKey];
68:
69: if (contextObject != null)
70: {
71: return (T)contextObject;
72: }
73: return default(T);
74: }
75:
76: /// <summary>
77: /// Creates and caches the data context.
78: /// </summary>
79: /// <typeparam name="T">Type of the data context.</typeparam>
80: /// <param name="contextInfoKey">The context info key.</param>
81: /// <returns>A new DataContext of the type requested.</returns>
82: protected T CreateAndCacheDataContext<T>(string contextInfoKey) where T : DataContext
83: {
84: var contextInfo = contextRegistry[contextInfoKey];
85:
86: if(contextInfo == null)
87: throw new ArgumentException("DataContext was not registered with the application.");
88:
89: if(contextInfo.Type != typeof(T))
90: throw new InvalidOperationException("Context is registered, but it's type does not match the type requested.");
91:
92: var dataContext = string.IsNullOrEmpty(contextInfo.ConnectionString)
93: ? (T)Activator.CreateInstance(typeof(T))
94: : (T)Activator.CreateInstance(typeof(T), new object[] { contextInfo.ConnectionString });
95:
96: DataContextCache[contextInfoKey] = dataContext;
97:
98: return dataContext;
99: }
100:
101:
102: private static bool IsWebApplication
103: {
104: get { return HttpContext.Current != null; }
105: }
106:
107: /// <summary>
108: /// Gets the context info key based on the contextKey and the DataContext type.
109: /// Used when registering and accessing a Data Context.
110: /// </summary>
111: /// <typeparam name="T">DataContext type.</typeparam>
112: /// <param name="contextKey">The context key.</param>
113: /// <returns>Key to be used when retrieving the data context.</returns>
114: protected static string GetContextInfoKey<T>(string contextKey)
115: {
116: return typeof(T).Name + (contextKey ?? "");
117: }