You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.6 KiB

2 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
2 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
2 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
  1. using System;
  2. using System.Reflection;
  3. using System.Threading;
  4. namespace Apewer.Web
  5. {
  6. /// <summary>API 上下文。</summary>
  7. public sealed class ApiContext
  8. {
  9. #region 构造参数
  10. private ApiInvoker _invoker = null;
  11. private ApiProvider _provider = null;
  12. private ApiEntries _entries = null;
  13. private DateTime _beginning = DateTime.Now;
  14. private ApiOptions _options = null;
  15. /// <summary>此上下文启动的时间。</summary>
  16. public DateTime Beginning { get => _beginning; }
  17. /// <summary>API 调用器。</summary>
  18. public ApiInvoker Invoker { get => _invoker; }
  19. /// <summary>API 提供程序。</summary>
  20. public ApiProvider Provider { get => _provider; }
  21. /// <summary>API 入口集。</summary>
  22. public ApiEntries Entries { get => _entries; }
  23. /// <summary>API 选项。</summary>
  24. public ApiOptions Options { get => _options; }
  25. #endregion
  26. #region 执行过程中产生的内容
  27. /// <summary>API 行为。</summary>
  28. public ApiAction ApiAction { get; internal set; }
  29. /// <summary>API 请求。</summary>
  30. public ApiRequest Request { get; internal set; }
  31. /// <summary>API 响应。</summary>
  32. public ApiResponse Response { get; internal set; }
  33. /// <summary>API 控制器实例。</summary>
  34. public ApiController Controller { get; internal set; }
  35. /// <summary>执行的方法。</summary>
  36. public MethodInfo MethodInfo { get; internal set; }
  37. #endregion
  38. #region 中间件
  39. Action<ApiContext> _middleware_callback = null;
  40. /// <summary>设置中间件回调。</summary>
  41. internal void SetMiddlewareCallback(Action<ApiContext> callback) => _middleware_callback = callback;
  42. /// <summary>继续执行。</summary>
  43. public void Next() => _middleware_callback?.Invoke(this);
  44. #endregion
  45. #region Current
  46. #if NET461_OR_GREATER || NETSTANDARD || NETCOREAPP
  47. static AsyncLocal<ApiContext> _current = new AsyncLocal<ApiContext>();
  48. #endif
  49. static void SetCurrent(ApiContext context)
  50. {
  51. #if NET461_OR_GREATER || NETSTANDARD || NETCOREAPP
  52. _current.Value = context;
  53. #else
  54. System.Runtime.Remoting.Messaging.CallContext.LogicalSetData("ApiContext", context);
  55. #endif
  56. }
  57. static ApiContext GetCurrent()
  58. {
  59. #if NET461_OR_GREATER || NETSTANDARD || NETCOREAPP
  60. if (_current == null) return null;
  61. return _current.Value;
  62. #else
  63. return System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("ApiContext") as ApiContext;
  64. #endif
  65. }
  66. /// <summary>获取当前的 <see cref="ApiContext" /> 实例。</summary>
  67. public static ApiContext Current { get => GetCurrent(); }
  68. #endregion
  69. internal ApiContext(ApiInvoker invoker, ApiProvider provider, ApiEntries entries)
  70. {
  71. if (invoker == null) throw new ArgumentNullException(nameof(invoker));
  72. if (provider == null) throw new ArgumentNullException(nameof(provider));
  73. if (entries == null) throw new ArgumentNullException(nameof(entries));
  74. _invoker = invoker;
  75. _provider = provider;
  76. _entries = entries;
  77. _options = invoker.Options ?? new ApiOptions();
  78. SetCurrent(this);
  79. }
  80. /// <summary>自定义数据。若此自定义数据实现了 <see cref="IDisposable" />,将会与 Context 一起自动释放。</summary>
  81. public object Data { get; set; }
  82. }
  83. }