DataContextAmbientScopeProvider.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using System;
  2. using System.Collections.Concurrent;
  3. using Abp.Collections.Extensions;
  4. using Castle.Core.Logging;
  5. using JetBrains.Annotations;
  6. namespace Abp.Runtime.Remoting
  7. {
  8. public class DataContextAmbientScopeProvider<T> : IAmbientScopeProvider<T>
  9. {
  10. public ILogger Logger { get; set; }
  11. private static readonly ConcurrentDictionary<string, ScopeItem> ScopeDictionary = new ConcurrentDictionary<string, ScopeItem>();
  12. private readonly IAmbientDataContext _dataContext;
  13. public DataContextAmbientScopeProvider([NotNull] IAmbientDataContext dataContext)
  14. {
  15. Check.NotNull(dataContext, nameof(dataContext));
  16. _dataContext = dataContext;
  17. Logger = NullLogger.Instance;
  18. }
  19. public T GetValue(string contextKey)
  20. {
  21. var item = GetCurrentItem(contextKey);
  22. if (item == null)
  23. {
  24. return default(T);
  25. }
  26. return item.Value;
  27. }
  28. public IDisposable BeginScope(string contextKey, T value)
  29. {
  30. var item = new ScopeItem(value, GetCurrentItem(contextKey));
  31. if (!ScopeDictionary.TryAdd(item.Id, item))
  32. {
  33. throw new AbpException("Can not add item! ScopeDictionary.TryAdd returns false!");
  34. }
  35. _dataContext.SetData(contextKey, item.Id);
  36. return new DisposeAction(() =>
  37. {
  38. ScopeDictionary.TryRemove(item.Id, out item);
  39. if (item.Outer == null)
  40. {
  41. _dataContext.SetData(contextKey, null);
  42. return;
  43. }
  44. _dataContext.SetData(contextKey, item.Outer.Id);
  45. });
  46. }
  47. private ScopeItem GetCurrentItem(string contextKey)
  48. {
  49. var objKey = _dataContext.GetData(contextKey) as string;
  50. return objKey != null ? ScopeDictionary.GetOrDefault(objKey) : null;
  51. }
  52. private class ScopeItem
  53. {
  54. public string Id { get; }
  55. public ScopeItem Outer { get; }
  56. public T Value { get; }
  57. public ScopeItem(T value, ScopeItem outer = null)
  58. {
  59. Id = Guid.NewGuid().ToString();
  60. Value = value;
  61. Outer = outer;
  62. }
  63. }
  64. }
  65. }