標籤:des style blog io color ar 使用 sp for
做了2年的介面開發,主要給移動端提供介面,整理了一套小工具,在這裡記錄一下。
1.非空欄位檢測
介面某些欄位不可為空,最開始進行空值檢測是在方法裡面,一個參數一個參數手動的檢測是否為空白,某些方法非空欄位十幾個的時候,代碼臃腫,看著噁心,寫著也煩,於是就利用特性和反射實現了自動空值檢測。
//特性聲明
[AttributeUsage(AttributeTargets.Property)] public class NotNull : Attribute { }
//使用方式
public class GetOrderListReq { [NotNull] public string uid { get; set; } }
//檢測方法,CustomExp是我自訂的錯誤類
public void NotNullCheck(object t) { var ps = t.GetType().GetProperties(); foreach (var item in ps) { //var c = item.GetCustomAttributes(typeof(NotNull), false).FirstOrDefault(m => m.GetType().Name == "NotNull"); var c = (NotNull)Attribute.GetCustomAttribute(item, typeof(NotNull)); if (c != null) { if (item.GetValue(t, null) == null) throw new CustomExp(4, item.Name + "不可為空!"); } } }
檢測流程。提前約定所有方法的形參均為一個類對象,在調用方法前先把實參檢測一遍,成功了再調用方法。
2.預設值設定
其實和非空檢測大同小異,C#有提供一個DefaultValue特性,不過我習慣用自己的東西~
[AttributeUsage(AttributeTargets.Property)] public class MyDefaultValue : Attribute { //預設值 public object Value { get; set; } }
public class GetOrderListReq { [NotNull] public string uid { get; set; } [NotNull] public DateTime ltime { get; set; } [MyDefaultValue(Value = 1)] public int index { get; set; } [MyDefaultValue(Value = 10)] public int size { get; set; } }
public void SetDefaultValue(object t) { var a = t.GetType().GetProperties(); foreach (var item in a) { var deault = (MyDefaultValue)Attribute.GetCustomAttribute(item, typeof(MyDefaultValue)); if (deault != null) { item.SetValue(t, deault.Value, null); } } }
3.方法路由
介面方法可能成百上千,如果用if或switch判斷調用哪個方法能寫到人奔潰~所以我用反射寫了個方法路由,速度肯定沒if快,但是就算介面有1000個方法,遍曆一遍也用不了多久,所以這點效能損失可以接受。類名+方法名確定唯一一個方法,arguments是方法實參對象的json字串。傳回值是一個類對象,視前端需要可以進行json序列化或xml序列化
public object GetEntry(string className, string MethodName, string arguments) { var ts = Assembly.GetExecutingAssembly().GetTypes(); object response = ""; bool notSuch = true; Type resType; Type reqType; foreach (var t in ts) { if (t.Name == className) { //執行個體類對象 var objClass = Assembly.GetExecutingAssembly().CreateInstance(t.FullName); //擷取類裡面的方法 MethodInfo m = t.GetMethod(MethodName); if (m != null) { notSuch = false; //擷取請求及響應對象的類型 resType = m.ReturnType; if (m.GetParameters().Count() > 0) { reqType = m.GetParameters()[0].ParameterType; if (arguments == null) throw new CustomExp(2, "該介面的參數不可為空!"); } else { reqType = null; } //還原序列化字串參數,產生參數對象並放入參數隊列 object[] arg = new object[1]; if (!string.IsNullOrEmpty(arguments) && reqType != null) { arg[0] = Json.JsonDes(arguments, reqType); } else arg = null; //執行方法並擷取返回的對象並序列化為字串 try { //參數不為空白則進行非空檢測及預設值設定 if (arg != null) { NotNullCheck(arg[0]); SetDefaultValue(arg[0]); } response = m.Invoke(objClass, arg); break; } catch (Exception E) { //擷取內部傳遞的異常,因為invoke會自動增加一層調用方法錯誤異常 throw E.GetBaseException(); } } } } if (notSuch) throw new CustomExp(3, "介面不存在!"); return response; }
C# 介面開發小工具 筆記