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
118 lines
3.6 KiB
using System;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
|
|
namespace Apewer.Web
|
|
{
|
|
|
|
/// <summary>API 上下文。</summary>
|
|
public sealed class ApiContext
|
|
{
|
|
|
|
#region 构造参数
|
|
|
|
private ApiInvoker _invoker = null;
|
|
private ApiProvider _provider = null;
|
|
private ApiEntries _entries = null;
|
|
|
|
private DateTime _beginning = DateTime.Now;
|
|
private ApiOptions _options = null;
|
|
|
|
/// <summary>此上下文启动的时间。</summary>
|
|
public DateTime Beginning { get => _beginning; }
|
|
|
|
/// <summary>API 调用器。</summary>
|
|
public ApiInvoker Invoker { get => _invoker; }
|
|
|
|
/// <summary>API 提供程序。</summary>
|
|
public ApiProvider Provider { get => _provider; }
|
|
|
|
/// <summary>API 入口集。</summary>
|
|
public ApiEntries Entries { get => _entries; }
|
|
|
|
/// <summary>API 选项。</summary>
|
|
public ApiOptions Options { get => _options; }
|
|
|
|
#endregion
|
|
|
|
#region 执行过程中产生的内容
|
|
|
|
/// <summary>API 行为。</summary>
|
|
public ApiAction ApiAction { get; internal set; }
|
|
|
|
/// <summary>API 请求。</summary>
|
|
public ApiRequest Request { get; internal set; }
|
|
|
|
/// <summary>API 响应。</summary>
|
|
public ApiResponse Response { get; internal set; }
|
|
|
|
/// <summary>API 控制器实例。</summary>
|
|
public ApiController Controller { get; internal set; }
|
|
|
|
/// <summary>执行的方法。</summary>
|
|
public MethodInfo MethodInfo { get; internal set; }
|
|
|
|
#endregion
|
|
|
|
#region 中间件
|
|
|
|
Action<ApiContext> _middleware_callback = null;
|
|
|
|
/// <summary>设置中间件回调。</summary>
|
|
internal void SetMiddlewareCallback(Action<ApiContext> callback) => _middleware_callback = callback;
|
|
|
|
/// <summary>继续执行。</summary>
|
|
public void Next() => _middleware_callback?.Invoke(this);
|
|
|
|
#endregion
|
|
|
|
#region Current
|
|
|
|
#if NET461_OR_GREATER || NETSTANDARD || NETCOREAPP
|
|
static AsyncLocal<ApiContext> _current = new AsyncLocal<ApiContext>();
|
|
#endif
|
|
|
|
static void SetCurrent(ApiContext context)
|
|
{
|
|
#if NET461_OR_GREATER || NETSTANDARD || NETCOREAPP
|
|
_current.Value = context;
|
|
#else
|
|
System.Runtime.Remoting.Messaging.CallContext.LogicalSetData("ApiContext", context);
|
|
#endif
|
|
}
|
|
|
|
static ApiContext GetCurrent()
|
|
{
|
|
#if NET461_OR_GREATER || NETSTANDARD || NETCOREAPP
|
|
if (_current == null) return null;
|
|
return _current.Value;
|
|
#else
|
|
return System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("ApiContext") as ApiContext;
|
|
#endif
|
|
}
|
|
|
|
/// <summary>获取当前的 <see cref="ApiContext" /> 实例。</summary>
|
|
public static ApiContext Current { get => GetCurrent(); }
|
|
|
|
#endregion
|
|
|
|
internal ApiContext(ApiInvoker invoker, ApiProvider provider, ApiEntries entries)
|
|
{
|
|
if (invoker == null) throw new ArgumentNullException(nameof(invoker));
|
|
if (provider == null) throw new ArgumentNullException(nameof(provider));
|
|
if (entries == null) throw new ArgumentNullException(nameof(entries));
|
|
|
|
_invoker = invoker;
|
|
_provider = provider;
|
|
_entries = entries;
|
|
_options = invoker.Options ?? new ApiOptions();
|
|
|
|
SetCurrent(this);
|
|
}
|
|
|
|
/// <summary>自定义数据。若此自定义数据实现了 <see cref="IDisposable" />,将会与 Context 一起自动释放。</summary>
|
|
public object Data { get; set; }
|
|
|
|
}
|
|
|
|
}
|