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.
|
|
using System; using System.Collections.Generic; using System.Reflection;
namespace Apewer.Web {
/// <summary></summary>
public sealed class ApiApplication : IToJson {
#region fields
Type _type = null; string _module = null;
// ApiAttribute
string _name = null; string _caption = null; string _description = null;
// invoke & enumerate
bool _independent = false; bool _hidden = false;
// functions
Dictionary<string, ApiFunction> _dict = new Dictionary<string, ApiFunction>(); List<ApiFunction> _list = new List<ApiFunction>();
#endregion
#region properties
/// <summary></summary>
public Type Type { get => _type; }
/// <summary></summary>
public string Module { get => _module; }
/// <summary></summary>
public string Name { get => _name; }
/// <summary></summary>
public string Caption { get => _caption; }
/// <summary></summary>
public string Description { get => _description; }
/// <summary></summary>
public bool Independent { get => _independent; }
/// <summary></summary>
public bool Hidden { get => _hidden; }
/// <summary></summary>
public ApiFunction[] Functions { get => _list.ToArray(); }
#endregion
/// <summary></summary>
public ApiApplication(Type type, ApiAttribute api) { // type
_type = type;
// api
if (api == null) { _name = type?.Name; } else { _name = string.IsNullOrEmpty(api.Name) ? type?.Name : api.Name; _caption = api.Caption; _description = api.Description; }
if (type != null) { // caption
if (string.IsNullOrEmpty(_caption)) { var captions = type.GetCustomAttributes(typeof(CaptionAttribute), true); if (captions.Length > 0) { var caption = (CaptionAttribute)captions[0]; _caption = caption.Title; if (string.IsNullOrEmpty(_description)) { _description = caption.Description; } } }
// hidden
if (type.Contains<HiddenAttribute>(false)) _hidden = true;
// independent
if (type.Contains<IndependentAttribute>(false)) _independent = true;
// Module
var assemblyName = type.Assembly.GetName(); _module = TextUtility.Join("-", assemblyName.Name, assemblyName.Version.ToString());
// functions
var funcs = new Dictionary<string, ApiFunction>(); var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (var method in methods) { var func = ApiFunction.Parse(this, method); if (func == null) continue;
var funcKey = func.Name.Lower(); if (funcs.ContainsKey(funcKey)) continue; funcs.Add(funcKey, func); } _dict = funcs;
_list.AddRange(funcs.Values); _list.Sort(new Comparison<ApiFunction>((a, b) => a.Name.CompareTo(b.Name))); } }
internal ApiFunction GetFunction(string name) { if (string.IsNullOrEmpty(name)) return null; if (_dict.TryGetValue(name.ToLower(), out var func)) return func; return null; }
/// <summary></summary>
public Json ToJson() => ToJson(new ApiOptions());
internal Json ToJson(ApiOptions options) { if (Hidden) return null;
var json = Json.NewObject(); json.SetProperty("name", _name); if (!string.IsNullOrEmpty(_caption)) json.SetProperty("caption", _caption); if (!string.IsNullOrEmpty(_description)) json.SetProperty("description", _description); if (options != null) { if (options.WithTypeName) json.SetProperty("type", _type.FullName); if (options.WithModuleName) json.SetProperty("mudule", _module); if (options.AllowEnumerate) json.SetProperty("functions", Json.From(_list)); } return json; }
/// <summary>解析类型,获取 <see cref="ApiApplication"/> 实例。</summary>
/// <param name="type">要解析的类型。</param>
/// <param name="requireAttribute">要求此类型拥有 Api 特性。</param>
/// <returns>解析成功返回实例,解析失败返回 NULL 值。</returns>
public static ApiApplication Parse(Type type, bool requireAttribute) { if (type == null) return null;
// 检查类型的属性。
if (!type.IsClass) return null; if (type.IsAbstract) return null; if (type.IsGenericType) return null; if (type.GetGenericArguments().NotEmpty()) return null; if (!RuntimeUtility.CanNew(type)) return null;
// 判断基类。
if (!typeof(ApiController).IsAssignableFrom(type)) return null;
// 检查类型的特性。
var apis = type.GetCustomAttributes(typeof(ApiAttribute), false); var api = apis.Length > 0 ? (ApiAttribute)apis[0] : null; if (requireAttribute && api == null) return null;
return new ApiApplication(type, api); }
}
}
|