小編給大家分享一下C#中擴(kuò)展命令的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
成都創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站建設(shè)、成都網(wǎng)站制作與策劃設(shè)計(jì),灤南網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:灤南等地區(qū)。灤南做網(wǎng)站價(jià)格咨詢:18980820575需求
我還不清楚這種方式是模式還是框架開發(fā)中用到的技術(shù),我暫且叫它為命令控制器吧。
命令控制器的主要功能就是獲取用戶提供的命令,然后來(lái)執(zhí)行命令。 在這里我把要執(zhí)行的“命令”設(shè)計(jì)成一個(gè)函數(shù),會(huì)對(duì)應(yīng)著一個(gè)String類型的命令字符串,并且命令控制器是允許擴(kuò)展的。
實(shí)現(xiàn)
首先我定義了一個(gè)屬性類,用于在擴(kuò)展的命令類、或者命令函數(shù)上,只有一個(gè)CommandName屬性,作用于命令函數(shù)上的話,則代表命令名稱,如果是作用于類上面的話就代表命令類別的名稱,只是考慮可以作為一個(gè)分類,這部分在后面有講到,可以自定義實(shí)現(xiàn)。
1 ///2 /// 命令所用代碼屬性類 3 /// 4 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 5 public class CommandAttribute : Attribute 6 { 7 private string commandName = null; 8 9 public string CommandName 10 { 11 get { return commandName; } 12 set { commandName = value; } 13 } 14 15 public CommandAttribute(string CommandName) 16 { 17 commandName = CommandName; 18 } 19 }
有了這個(gè)屬性類了,我們就要把它用起來(lái),定義一些后面要用到的命令示例類,
1 ///2 /// 示例:命令類以及命令函數(shù),亦可當(dāng)作為擴(kuò)展 3 /// 4 [Command("Test")] 5 public class CommandTest : CommandMethod 6 { 7 [Command("MyCommandone")] 8 public object test(ICommandParameter commandparameter) 9 { 10 return null; 11 } 12 13 [Command("MyCommandone1")] 14 public object test1(ICommandParameter commandparameter) 15 { 16 return null; 17 } 18 19 [Command("MyCommandone2")] 20 public object test2(ICommandParameter commandparameter) 21 { 22 return null; 23 } 24 25 26 [Command("MyCommandone3")] 27 public object test3(ICommandParameter commandparameter) 28 { 29 return null; 30 } 31 32 [Command("MyCommandone4")] 33 public object test4(ICommandParameter commandparameter) 34 { 35 return null; 36 } 37 }
上面的示例代碼中可以看到CommandTest類繼承自CommandMethod類,而類里面的一些函數(shù)的簽名也是一樣的,函數(shù)參數(shù)都為ICommandParameter接口類型,這就是擴(kuò)展命令方法時(shí)要遵循的一些規(guī)范,定義的規(guī)范:
1 ///2 /// 擴(kuò)展命令函數(shù)的參數(shù)規(guī)范 3 /// 4 public interface ICommandParameter 5 { 6 7 } 8 9 ///10 /// 擴(kuò)展命令方法類基類 11 /// 12 public class CommandMethod 13 { 14 15 }
需要實(shí)現(xiàn)什么都是可以自定義,比如說(shuō)可以在ICommandParameter接口中定義個(gè)object類型的名稱為ContainerObject的屬性,意思就是容器屬性,可以在后面調(diào)用命令時(shí),傳入實(shí)例參數(shù)時(shí)設(shè)置容器屬性的值,可以設(shè)置為任何你想設(shè)置的值到里面,然后再在命令函數(shù)里使用它,也可以根據(jù)抽象定義實(shí)現(xiàn)一個(gè)參數(shù)上下文對(duì)象專門用于處理擴(kuò)展命令的,看需要自定義吧。
然后就是書寫一個(gè)命令控制器的代碼了,它呢主要負(fù)責(zé)把客戶端注冊(cè)進(jìn)來(lái)的類型做一些處理,比如說(shuō) 判斷類型、反射類型獲取函數(shù)命令以及函數(shù)信息、把命令函數(shù)轉(zhuǎn)換成委托、維護(hù)命令列表等等一些簡(jiǎn)單的功能,還用到了一個(gè)CommandMethodActionDelegate類型的委托:
1 public delegate object CommandMethodActionDelegate(ICommandParameter commandParameter); 2 3 public class CommandController 4 { 5 private static CommandController _Instance = null; 6 7 public static CommandController Instance 8 { 9 get 10 { 11 if (_Instance == null) 12 { 13 _Instance = new CommandController(HostDevelopment.Instance); 14 } 15 return _Instance; 16 } 17 } 18 19 private HostDevelopment _CommandDevelopment = HostDevelopment.Instance; 20 21 public CommandController(HostDevelopment commandDevelopment) 22 { 23 _CommandDevelopment = commandDevelopment; 24 } 25 26 private Dictionarycommandlist = new Dictionary (); 27 28 29 private List _commandNames = null; 30 /// 31 /// 命令名稱集合 32 /// 33 public ListCommandNames 34 { 35 get 36 { 37 if (_commandNames == null) 38 { 39 GetCommandNames(); 40 } 41 return _commandNames; 42 } 43 } 44 45 private void GetCommandNames() 46 { 47 48 if (commandlist.Count > 0) 49 { 50 if (_commandNames == null) 51 { 52 _commandNames = new List (); 53 } 54 foreach (string name in commandlist.Keys) 55 { 56 _commandNames.Add(name); 57 } 58 } 59 } 60 61 public bool RegisterCommand(object instance) 62 { 63 Type t = instance.GetType(); 64 CommandAttribute cmdatt = (CommandAttribute)Attribute.GetCustomAttribute(t, typeof(CommandAttribute), false); 65 if (cmdatt != null) 66 { 67 AddCommandToModel(instance); 68 return true; 69 } 70 else { return false; } 71 } 72 73 private void AddCommandToModel(object instance) 74 { 75 Type t = instance.GetType(); 76 MethodInfo[] methods = t.GetMethods(); 77 foreach (MethodInfo methodinfo in methods) 78 { 79 CommandAttribute cmdatt = (CommandAttribute)Attribute.GetCustomAttribute(methodinfo, typeof(CommandAttribute), false); 80 if (cmdatt != null) 81 { 82 83 CommandMethodActionDelegate commanddelegate = (CommandMethodActionDelegate)Delegate.CreateDelegate(typeof(CommandMethodActionDelegate), instance, methodinfo.Name); 84 commandlist.Add(cmdatt.CommandName, commanddelegate); 85 } 86 87 } 88 } 89 90 91 internal object Execute(string commandName, ICommandParameter commandParameter) 92 { 93 if (commandName == null) 94 { 95 throw new ArgumentNullException("commandName"); 96 } 97 if (!commandlist.ContainsKey(commandName)) 98 { 99 return new ArgumentNullException("不包含的命令,命令無(wú)效"); 100 } 101 CommandMethodActionDelegate cmdaction = commandlist[commandName]; 102 return cmdaction.Invoke(commandParameter); 103 } 104 }
在CommandController類型中,RegisterCommand()方法為注冊(cè)擴(kuò)展命令到命令控制器,示例中的注冊(cè)方式為手動(dòng)的傳入類型實(shí)例來(lái)注冊(cè)的,也可以把實(shí)現(xiàn)方式修改為在命令控制器啟動(dòng)的時(shí)候獲取當(dāng)前系統(tǒng)所有依賴項(xiàng)的程序集,獲取到所有符合類型規(guī)范的擴(kuò)展命令類型,并且注冊(cè)到控制器中。
上面代碼中有說(shuō)到的HostDevelopment類型,是我定義的一個(gè)宿主容器對(duì)象,用它來(lái)承載命令控制器,以及在這個(gè)系列的文章中,都是使用HostDevelopment來(lái)進(jìn)行對(duì)控制器的承載,這是后話。現(xiàn)在來(lái)看一下HostDevelopment暫時(shí)的定義:
1 public delegate object CommandMethodActionDelegate(ICommandParameter commandParameter); 2 3 public class CommandController 4 { 5 private static CommandController _Instance = null; 6 7 public static CommandController Instance 8 { 9 get 10 { 11 if (_Instance == null) 12 { 13 _Instance = new CommandController(HostDevelopment.Instance); 14 } 15 return _Instance; 16 } 17 } 18 19 private HostDevelopment _CommandDevelopment = HostDevelopment.Instance; 20 21 public CommandController(HostDevelopment commandDevelopment) 22 { 23 _CommandDevelopment = commandDevelopment; 24 } 25 26 private Dictionarycommandlist = new Dictionary (); 27 28 29 private List _commandNames = null; 30 /// 31 /// 命令名稱集合 32 /// 33 public ListCommandNames 34 { 35 get 36 { 37 if (_commandNames == null) 38 { 39 GetCommandNames(); 40 } 41 return _commandNames; 42 } 43 } 44 45 private void GetCommandNames() 46 { 47 48 if (commandlist.Count > 0) 49 { 50 if (_commandNames == null) 51 { 52 _commandNames = new List (); 53 } 54 foreach (string name in commandlist.Keys) 55 { 56 _commandNames.Add(name); 57 } 58 } 59 } 60 61 public bool RegisterCommand(object instance) 62 { 63 Type t = instance.GetType(); 64 CommandAttribute cmdatt = (CommandAttribute)Attribute.GetCustomAttribute(t, typeof(CommandAttribute), false); 65 if (cmdatt != null) 66 { 67 AddCommandToModel(instance); 68 return true; 69 } 70 else { return false; } 71 } 72 73 private void AddCommandToModel(object instance) 74 { 75 Type t = instance.GetType(); 76 MethodInfo[] methods = t.GetMethods(); 77 foreach (MethodInfo methodinfo in methods) 78 { 79 CommandAttribute cmdatt = (CommandAttribute)Attribute.GetCustomAttribute(methodinfo, typeof(CommandAttribute), false); 80 if (cmdatt != null) 81 { 82 83 CommandMethodActionDelegate commanddelegate = (CommandMethodActionDelegate)Delegate.CreateDelegate(typeof(CommandMethodActionDelegate), instance, methodinfo.Name); 84 commandlist.Add(cmdatt.CommandName, commanddelegate); 85 } 86 87 } 88 } 89 90 91 internal object Execute(string commandName, ICommandParameter commandParameter) 92 { 93 if (commandName == null) 94 { 95 throw new ArgumentNullException("commandName"); 96 } 97 if (!commandlist.ContainsKey(commandName)) 98 { 99 return new ArgumentNullException("不包含的命令,命令無(wú)效"); 100 } 101 CommandMethodActionDelegate cmdaction = commandlist[commandName]; 102 return cmdaction.Invoke(commandParameter); 103 } 104 }
看了這些了,應(yīng)該就大致的明白了,不過現(xiàn)在這樣的代碼還是測(cè)試不了的,因?yàn)槿鄙僖恍?shí)體。定義一個(gè)默認(rèn)實(shí)現(xiàn)的命令參數(shù)規(guī)范:
1 public class CommandParameterCase:ICommandParameter 2 { 3 private string _StrText; 4 5 public string StrText 6 { 7 get { return _StrText; } 8 set { _StrText = value; } 9 } 10 }
然后再修改一下CommandTest類型中的第一個(gè)叫test的函數(shù)(對(duì)應(yīng)的命令名稱為MyCommandone),函數(shù)名稱有點(diǎn)隨意,大家不要介意這些。
1 [Command("MyCommandone")] 2 public object test(ICommandParameter commandparameter) 3 { 4 if (commandparameter != null) 5 { 6 CommandParameterCase commandparametercase = commandparameter as CommandParameterCase; 7 return commandparametercase.StrText; 8 } 9 else { return null; } 10 }
這樣所需的都定義齊了。 我們?cè)倏匆幌抡{(diào)用代碼:
1 HostDevelopment.Instance.Start(); 2 HostDevelopment.Instance.CommandController.RegisterCommand(new CommandTest()); 3 var strtext = HostDevelopment.Instance.Execute("MyCommandone", new CommandParameterCase() { StrText = "test" });
對(duì)了隨便是打個(gè)斷點(diǎn)或者是輸出strtext都可以看到它的值。這里不作多的解釋了。
以上是“C#中擴(kuò)展命令的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站制作公司行業(yè)資訊頻道!
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。