Monday, May 30, 2011

Scenario management for .ashx handlers.

    /// <summary>
    /// Scenario has three parts
    /// 1. A test that returns true or false
    /// 2. A method to run if the test is true.
    /// 3. A response object that has some details such as error messages.
    /// 
    /// Benefits, your main entry point to the application is clean.
    /// The scenarios should be of a relatively similar type, this is not a service locator.
    /// For example the file up loader has three different save types, so there are three different scenarios.
    /// 
    /// </summary>
    public class ScenarioHttpContext
    {
 
        public Func<HttpContextbool> Test { getset; }
        public Func<HttpContextScenarioResponse> DoWork { getset; }
 
        [DebuggerStepThrough]
        public ScenarioHttpContext(Func<HttpContextbool> test, Func<HttpContextScenarioResponse> doWork)
        {
            Test = test;
            DoWork = doWork;
        }
 
        [DebuggerStepThrough]
        public static List<ScenarioResponse> RunActions(List<ScenarioHttpContext> scenarios, HttpContext context,bool runAll = false)
        {
            Contract.Requires<ArgumentNullException>(context != null);
            Contract.Requires<ArgumentNullException>( scenarios != null);
            Contract.Requires<ArgumentOutOfRangeException>(scenarios != null || scenarios.Count > 0, "Cannot be null or have zero list items.");
            Trace.WriteLine("Starting ->" + MethodBase.GetCurrentMethod().Name); 
            Trace.Indent();
            var resp = new List<ScenarioResponse>();
           
            //if the test returns true then run the method
            foreach (var scenario in scenarios.Where(scenario => scenario.Test(context)))
            {
               
                Trace.WriteLine(scenario + "Was called.");
                var a = scenario.DoWork(context);
                a.Name = scenario.ToString();
 
                resp.Add(a);
                
                if (!runAll) { break; }
            }
 
            Trace.WriteLine(string.Format("A total of {0} scenarios evaluated true and ran.", resp.Count.ToString()));
            Trace.Unindent();
            Trace.WriteLine("Ending ->" + MethodBase.GetCurrentMethod().Name);
            Trace.Flush();
            return resp;
        }
    }
 
    public class ScenarioResponse
    {
        public string Name { getset; }
        public bool Success { getset; }
        public string ErrorMsg { getset; }
    }
 
 
    public static class ScenarioHttpContextExtensions
    {
       /// <summary>
       /// 
       /// </summary>
       /// <param name="scenario">Unit of work</param>
       /// <param name="test">If statement to determine if this scenario should be run.</param>
       /// <param name="workToDo">The work to do if the scenario test is true</param>
        [DebuggerStepThrough]
        public static void AddNew(this List<ScenarioHttpContext> scenario ,Func<HttpContextbool> test, Func<HttpContext,ScenarioResponse > workToDo)
        {
            Contract.Requires<ArgumentNullException>(scenario != null);
            scenario.Add(new ScenarioHttpContext(test, workToDo));
        }
    }

No comments:

Post a Comment