Remember it once. NET code refactoring (bottom)

Source: Internet
Author: User
public override bool Trygetmember (GetMemberBinder binder, out object result) { if (!_dictionary. TryGetValue (binder.                Name, out result)) {result = null;            return true;            } var dictionary = result as idictionary<string, object>;                if (dictionary! = null) {result = new Dynamicjsonobject (dictionary);            return true;            } var arrayList = result as arrayList; if (arrayList! = null && arraylist.count > 0) {if (arraylist[0] is idictionary<st Ring, object>) result = new List<object> (arraylist.cast<idictionary<string, object>> ().                Select (x = new Dynamicjsonobject (x)));            else result = new List<object> (arraylist.cast<object> ());        } return true; }} #endregion} 

Next is the GetContent method, the purpose of this method is simple, is to according to the customer passed the template variable parameter key value pairs and text message template content, assembled into the final text message sent content, before this method is hard-coded, and now we need to become dynamic acquisition.

Sample content for SMS templates:

"One should life" you have a ticket for expressnumbers company, has arrived in the CommunityName mailroom, please open the one should life app "mailroom" to get the pickup code to take the pieces. Click to download Http://a.app.qq.com/o/simple.jsp?pkgname=com.ening.life

I found that the template content is problematic, the variables in the template parameters are directly used in English words, and our text message content may sometimes exist in English words, then I will give all the variable parameter {}. The following changes are followed:

"One should life" you have a ticket for {expressnumbers} {company}, to the {communityname} mailroom, please open the one should life app mailroom to get the pickup code for pickup. Click to download Http://a.app.qq.com/o/simple.jsp?pkgname=com.ening.life

We need to replace the variable parameter in the text message template with the value corresponding to the variable parameter according to the object passed by the customer. Then we first need to parse the key-value pair information in this object.

  Gets the property reflection of object objects to the dictionary list        ///</summary>//<param name= "Data" >object objects </param>        // /<returns> Returns a list of Dictionary (property names, property values) </returns>         static dictionary<string, string> GetProperties (Object data)        {            dictionary<string, string> dict = new dictionary<string, string> ();            Type type = data. GetType ();            string[] PropertyNames = type. GetProperties (). Select (p = = p.name). ToArray ();            foreach (Var prop in propertynames)            {                Object propvalue = type. GetProperty (prop). GetValue (data, null);                String value = (PropValue! = null)? Propvalue.tostring (): "";                if (!dict. ContainsKey (prop))                {                    dict. ADD (prop, value);                }            }            return dict;        }

The next step is to match the text message template content with regular expressions.

  Multiple matches///</summary>//<param name= "sInput" > Input </param>//<param Nam E= "Sregex" > Expression string </param>//<param name= "Sgroupname" > Group name, "" means no grouping </param> static List <string> GetList (String sInput, String Sregex, String sgroupname) {list<string> List = new            List<string> (); Regex re = new regex (Sregex, Regexoptions.ignorecase | Regexoptions.ignorepatternwhitespace |            Regexoptions.multiline); MatchCollection MCS = Re.            Matches (SInput); foreach (Match MC in MCS) {if (Sgroupname! = "") {list. ADD (MC. Groups[sgroupname].                Value); } else {list. ADD (MC.                Value);        }} return list; } public static string Replacetemplate (string template, Object data) {var regex = @ "\{(? <name>.*?)            \}"; list<string> itemList = GetList (template, Regex, "name");            Gets the template variable object dictionary<string, string> dict = GetProperties (data); foreach (string item in ItemList) {//If the property exists, replace the template and modify the template value if (Dict. ContainsKey (item)) {Template = template. Replace ("{" +item+ "}", Dict. First (x = X.key = = Item).                Value); }} return template;

This is to say that the client passes the object and our parsing code to understand the decoupling, the customer passes the object no longer relies on our code implementation, but relies on our data table in the template content configuration.

These methods I write well, by the way a unit test to verify whether I want the effect, poor, this project is useless to unit testing, no way, I create a unit test myself

[TestClass] public class Matchhelpertest {[TestMethod] public void replacetemplate () { Template text var templates = "One should life" you have a ticket for {expressnumbers} {company}, to {communityname} mailroom, please open the one should live app " The mailroom "gets the pickup code for the pickup.            Click to download Http://a.app.qq.com/o/simple.jsp?pkgname=com.ening.life ";            Data Object var = new {Expressnumbers = "", company = "Great Wall", CommunityName = "Chang Yee Garden"}; String str = "One should life" you have a ticket number of 2016 Great Wall, has reached the long Yee Garden mailroom, please open the one should life app "mailroom" to get the pickup code to pick up the pieces.            Click to download Http://a.app.qq.com/o/simple.jsp?pkgname=com.ening.life ";            String Str1=matchhelper.replacetemplate (template, data);            Assert.AreEqual (STR1,STR);            Duplicate label Test template = "One should life" you have a ticket for {expressnumbers} {company}, to {communityname} mailroom, Number: {expressnumbers} ";            str = "One should life" you have a ticket number of 2016 Great Wall, has reached the long Yee Garden mailroom, Dan: 2016 ";            Str1=matchhelper.replacetemplate (template, data);        Assert.AreEqual (str1, str); }    }

When it comes to unit testing, I believe that many companies are not using them for too many reasons. I also think that if the business is simple, there is no need to write unit testing, too many entrepreneurial companies in the domestic project progress is very rushed, if the write unit test does not take time, it is absolutely deceptive, as to say write unit test can improve development efficiency, reduce rework rate, personal feeling this is really difficult, Because even if you do not write unit testing can be done through a number of other means to compensate, personal views, do not spray.

Next, modify the GetContent method as follows:

public string getcontent (dynamic Messagecontext) {            string strMsg = "";            String TypeCode = String. IsNullOrEmpty (Messagecontext.servicecode)? "001": Messagecontext.servicecode;            String channel = Messagecontext.channel;            Try{var Module = UnitOfWork.MessageModule.Get (c = c.type = = Channel && C.typeno = = TypeCode). FirstOrDefault ();                if (!string. IsNullOrEmpty (module.content))                {                    var Content = module.content;                    STRMSG = matchhelper.replacetemplate (content, Messagecontext);                }                return STRMSG;            }            catch (Exception ex)            {                STRMSG = ex. Message;            }            return STRMSG;        }

(Out of the box: first spit the slot before this variable name, Messagecontext messagecontext and string messagecontent, look too much like, at first I refactor when I made a mistake, it is recommended not to use similar variable names in the same method, To avoid confusion. Mom eggs, the old driver I was again, angry, unbearable, decisive renaming. )


The original controller called the Business logic code is directly like this

Messagemodulebusiness messagemodulebusiness = new Messagemodulebusiness ()

Depends on the implementation of the specific class, and we know that the concrete is unstable, the abstraction is stable, we should be interface-oriented programming. Today is to send text messages, tomorrow may be e-mail, or to add log records and so on.

public interface imessagemodulebusiness{//<summary>///        Assembly message content///        </summary>        // <param name= "Messagecontext" > Dynamic Parameter Objects </param>//        <returns> assembled message content </returns>        String getcontent (Dynamic Messagecontext);}

The code that is then called is modified to:

Private imessagemodulebusiness messagemodulebusiness = new messagemodulebusiness ();

The final externalmerchantsendmessage code is:

    External merchant Send information public actionresult externalmerchantsendmessage () {try {                dynamic param = null;                String json = Request.QueryString.ToString ();                    if (Request.QueryString.Count! = 0)//ajax GET request {//compatible with old client call notation, temporarily hard-compiled if (JSON.                    Contains ("param.")) {JSON = json.                    Replace ("Param.", ""); JSON = "{" + JSON. Replace ("=", ":").                Replace ("&", "',") + "'}";                    The Else//ajax POST request {Request.InputStream.Position = 0;//Remember that you must set the start position of the stream to 0, otherwise you cannot read the data JSON = new StreamReader (request.inputstream).                ReadToEnd ();                } var serializer = new JavaScriptSerializer (); Serializer.                Registerconverters (new[] {new Dynamicjsonconverter ()}); param = serializer. Deserialize (JSON, typeof (object));               Logger.                Info ("[Externalmerchantsendmessage]param:" + param);                BOOL Isauth = Authmodelbusiness.isauth (Param.channel, Param.phone, param.sign);                        if (!isauth) {return Json (new result<string> () { ResultCode = ((int) resultcode.nopermission).                ToString (), resultmsg = "signed or no Access"}, Jsonrequestbehavior.allowget);                } var meaage = messagemodulebusiness.getcontent (param); if (string.                        IsNullOrEmpty (Meaage)) {return Json (new result<string> () { ResultCode = ((int) resultcode.failure).                ToString (), resultmsg = "Send Failed"}, Jsonrequestbehavior.allowget);                } smshelper helper = new Smshelper (); Helper. Sendsms (Meaage, Param.phone);  Send SMS              Return Json (New result<string> () {ResultCode = ((int) resultcode.suc Cess).            ToString (), resultmsg = "Send Success"}, Jsonrequestbehavior.allowget);                    } catch (Exception ex) {return Json (new result<string> () { ResultCode = ((int) resultcode.failure). ToString (), resultmsg = "Send Failed" +ex.            Message}, Jsonrequestbehavior.allowget); }        }

In this case, it is convenient to re-decouple it later by reflection or IOC.


Well, through such a step-by-step refactoring, without modifying the original table structure and without affecting the customer invocation, I have already encapsulated the change point, when the customer's template parameter variable changes, no longer need to change the code, only need to modify the template content in the table can be.

Refactoring, drawing class diagram is a very good habit, code structure at a glance, I enclose a class diagram here.

The above is to remember once. NET code refactoring (below) content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.