Saturday, June 26, 2010

Using Regular Expression Groups in Search and Replace

I needed to convert a series of numbers as in:

          19473
          20390
          22797
          23116
          ..

into

          list.Add(19473);
          list.Add(20390);
          list.Add(22797);
          list.Add(23116);
          ...

While I am not adverse to doing this manually or thru some macro, I was staring at 10000 of these so I can just hear my old boss saying "You are not lazy enough."

The solution is to use regular expressions. Using NotePad++,

 SearchAndReplace

The key here was to enclose in parenthesis the search pattern and reference that in the replace string as \1.

Sweet!

Tuesday, November 4, 2008

Broken Rules in the Domain

Technorati Tags:

I've been using the broken rules scheme in my past few projects and I like the way it raises the visibility of rules by making them a first class citizen of the domain. Rules will no longer be buried with the other "stuff" of a business transaction.  No sir, these rules have names! 

Take for example, a couple of rules around issuing inventory for a title insurance company:

  1. Provide the ability for management to block requests for new inventory from a specific agency.
  2. Provide the ability to stop issuing inventory to agencies whose contract has been canceled.
  3. Provide the ability to stop issuing inventory to agencies that have failed to meet minimum reporting requirements .
  4. Provide the ability to stop agencies from being issued inventory they are not authorized for.

Speaking close to the language of the domain, these rules are grouped as a set.  And for the sake of brevity, let us assume that these rules are independent of each other:

 

        private List<ValidationRuleBase> GetRulesForIssuingInventory(Agent agent, PolicyType requestedPolicyType, List<PolicyType> policyTypesAuthorizedForTheAgent)

        {

            var rules = new List<ValidationRuleBase>();

 

            rules.Add(new ShouldNot_Issue_To_Agents_That_Has_Been_Blocked_To_RequestInventory(agent));

            rules.Add(new ShouldNot_Issue_To_Cancelled_Agents(agent));

            rules.Add(new ShouldNot_Issue_To_Agents_That_Has_Not_Met_Minimum_Reporting_Requirements(agent));

            rules.Add(new Agent_ShouldBe_Authorized_To_Order_The_Requested_PolicyTypes(agent,requestedPolicyType, policyTypesAuthorizedForTheAgent));

 

            return rules;

        }

 


In this particular scenario, this set of rules hangs off the domain object 'Order'  and is checked when a request for inventory is received.

 

        public void PlaceAnOrder(Order order)

        {

            List<ValidationRuleBase> rules;

            List<ValidationRuleBase> brokenRules;

 

            rules = order.GetRulesForIssuingInventory(order.Agent, order.PolicyType, order.Agent.AuthorizedPolicyTypes);

            brokenRules = GetBrokenRules(rules);

            if (brokenRules.Count>0)

            {

                throw new BusinessRuleException(brokenRules);

            }

 

            // continue with the rest of the placing an order transaction

        }

 

 

An example of a rule implementation is:

 

    public class Agent_ShouldBe_Authorized_To_Order_The_Requested_PolicyTypes : ValidationRuleBase

    {

        private Agent agent;

        private PolicyType requestedPolicyType;

        private List<PolicyType> policyTypesAuthorizedForTheAgent;

 

        public Agent_ShouldBe_Authorized_To_Order_The_Requested_PolicyTypes(Agent agent, PolicyType requestedPolicyType, List<PolicyType> policyTypesAuthorizedForTheAgent)

        {

            this.agent                            = agent;

            this.requestedPolicyType              = requestedPolicyType;

            this.policyTypesAuthorizedForTheAgent = policyTypesAuthorizedForTheAgent;

        }

 

        override public bool IsValid

        {

            get

            {

                return this.policyTypesAuthorizedForTheAgent.Contains(this.requestedPolicyType);

            }

        }

 

        public override string Message

        {

            get

            {

                return String.Format("Policy Type {0} is not in the list of policy types Agent {1} can order.",this.requestedPolicyType.Name,this.agent.Name);

            }

        }

    }

 

 

Note in the IsValid() override that the heart of the rule is for the most part just plain logic and is devoid of UI and persistence concerns.   This leads to a more focused expression of the rule.