Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 8d15bc0

Browse files
committed
Add OrmLiteContext for holding async state, store state in CallContext by default
1 parent 29b8c5d commit 8d15bc0

File tree

5 files changed

+100
-7
lines changed

5 files changed

+100
-7
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Concurrent;
4+
using System.Collections.Generic;
5+
using System.Runtime.Remoting.Messaging;
6+
7+
namespace ServiceStack.OrmLite
8+
{
9+
public class OrmLiteContext
10+
{
11+
public static readonly OrmLiteContext Instance = new OrmLiteContext();
12+
13+
/// <summary>
14+
/// Tell ServiceStack to use ThreadStatic Items Collection for Context Scoped items.
15+
/// Warning: ThreadStatic Items aren't pinned to the same request in async services which callback on different threads.
16+
/// </summary>
17+
public static bool UseThreadStatic = false;
18+
19+
[ThreadStatic]
20+
public static IDictionary ContextItems;
21+
22+
/// <summary>
23+
/// Gets a list of items for this context.
24+
/// </summary>
25+
public virtual IDictionary Items
26+
{
27+
get
28+
{
29+
return GetItems() ?? (CreateItems());
30+
}
31+
set
32+
{
33+
CreateItems(value);
34+
}
35+
}
36+
37+
private const string _key = "__OrmLite.Items";
38+
39+
private IDictionary GetItems()
40+
{
41+
try
42+
{
43+
if (UseThreadStatic)
44+
return ContextItems;
45+
46+
return CallContext.LogicalGetData(_key) as IDictionary;
47+
}
48+
catch (NotImplementedException)
49+
{
50+
//Fixed in Mono master: https://github.com/mono/mono/pull/817
51+
return CallContext.GetData(_key) as IDictionary;
52+
}
53+
}
54+
55+
private IDictionary CreateItems(IDictionary items = null)
56+
{
57+
try
58+
{
59+
if (UseThreadStatic)
60+
{
61+
ContextItems = items ?? (items = new Dictionary<object, object>());
62+
}
63+
else
64+
{
65+
CallContext.LogicalSetData(_key, items ?? (items = new ConcurrentDictionary<object, object>()));
66+
}
67+
}
68+
catch (NotImplementedException)
69+
{
70+
//Fixed in Mono master: https://github.com/mono/mono/pull/817
71+
CallContext.SetData(_key, items ?? (items = new ConcurrentDictionary<object, object>()));
72+
}
73+
return items;
74+
}
75+
76+
public T GetOrCreate<T>(Func<T> createFn)
77+
{
78+
if (Items.Contains(typeof(T).Name))
79+
return (T)Items[typeof(T).Name];
80+
81+
return (T)(Items[typeof(T).Name] = createFn());
82+
}
83+
84+
internal static string LastCommandText
85+
{
86+
get
87+
{
88+
return Instance.Items["LastCommandText"] as string;
89+
}
90+
set
91+
{
92+
Instance.Items["LastCommandText"] = value ?? "";
93+
}
94+
}
95+
}
96+
}

src/ServiceStack.OrmLite/OrmLiteExecFilter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ public virtual IDbCommand CreateCommand(IDbConnection dbConn)
3535
var dbCmd = dbConn.CreateCommand();
3636
dbCmd.Transaction = (ormLiteDbConn != null) ? ormLiteDbConn.Transaction : OrmLiteConfig.TSTransaction;
3737
dbCmd.CommandTimeout = OrmLiteConfig.CommandTimeout;
38-
OrmLiteReadExpressionsApi.LastCommandText = null;
38+
OrmLiteContext.LastCommandText = null;
3939
return dbCmd;
4040
}
4141

4242
public virtual void DisposeCommand(IDbCommand dbCmd)
4343
{
4444
if (dbCmd == null) return;
45-
OrmLiteReadExpressionsApi.LastCommandText = dbCmd.CommandText;
45+
OrmLiteContext.LastCommandText = dbCmd.CommandText;
4646
dbCmd.Dispose();
4747
}
4848

src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ namespace ServiceStack.OrmLite
88
{
99
public static class OrmLiteReadExpressionsApi
1010
{
11-
[ThreadStatic]
12-
internal static string LastCommandText;
13-
1411
public static T Exec<T>(this IDbConnection dbConn, Func<IDbCommand, T> filter)
1512
{
1613
return OrmLiteConfig.ExecFilter.Exec(dbConn, filter);

src/ServiceStack.OrmLite/OrmLiteWriteApi.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static class OrmLiteWriteApi
1414
/// </summary>
1515
public static string GetLastSql(this IDbConnection dbConn)
1616
{
17-
return OrmLiteReadExpressionsApi.LastCommandText;
17+
return OrmLiteContext.LastCommandText;
1818
}
1919

2020
/// <summary>

src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
</ItemGroup>
106106
<ItemGroup>
107107
<Compile Include="AliasNamingStrategy.cs" />
108-
<Compile Include="Async\async.cs" />
108+
<Compile Include="OrmLiteContext.cs" />
109109
<Compile Include="OrmLiteReadApiAsync.cs" />
110110
<Compile Include="Async\OrmLiteReadCommandExtensionsAsync.cs" />
111111
<Compile Include="Async\OrmLiteResultsFilterExtensionsAsync.cs" />

0 commit comments

Comments
 (0)