Veritas Now that we’ve established our database and our initial project structure, we can finally start coding.  We’ll start our coding by creating some of the base objects we’re going to use throughout our application.  I know, after 4 entries, can’t we actually make the site show something?   We could but I don’t want to start showing stuff and then go back to refactor stuff if we can get some of it done ahead of time.

The first thing we’ll create is our repository class that' we’ll be using for Data Access.  We won’t actually handle our data access quite yet, but we’re going to create our interface for accessing that data.  We’ll add a new class to the DataLayer named “VeritasRepository”.  For now, we’ll just implement the repository pattern inside this class:

   1:  public class VeritasRepository
   2:      {
   3:          internal const string CACHE_KEY = "_VeritasRepository_Cache_Key";
   4:   
   5:          private VeritasRepository() { }
   6:   
   7:          /// <summary>
   8:          /// Static method to get an instance of our Veritas Repostiory.  
   9:          /// Checks to see if we have a context in case we're using 
  10:          /// this in a unit test.
  11:          /// </summary>
  12:          /// <returns></returns>
  13:          public static VeritasRepository GetInstance()
  14:          {
  15:              if (HttpContext.Current == null)
  16:                  return new VeritasRepository();
  17:   
  18:              if (HttpContext.Current.Items.Contains(CACHE_KEY))
  19:                  return (VeritasRepository)HttpContext.Current.Items[CACHE_KEY];
  20:   
  21:              VeritasRepository repo = new VeritasRepository();
  22:              HttpContext.Current.Items[CACHE_KEY] = repo;
  23:              return repo;
  24:          }
  25:   
  26:          /// <summary>
  27:          /// Forces us to get a new instace for testing purposes
  28:          /// </summary>
  29:          /// <returns></returns>
  30:          public static VeritasRepository ForceNewInstance()
  31:          {
  32:              VeritasRepository repo = new VeritasRepository();
  33:              if (HttpContext.Current.Items.Contains(CACHE_KEY))
  34:                  HttpContext.Current.Items[CACHE_KEY] = repo;
  35:              else
  36:                  HttpContext.Current.Items.Add(CACHE_KEY, repo);
  37:              return repo;
  38:          }
  39:   
  40:          /// <summary>
  41:          /// Will create a new transation.  Not implemented now but will be later.
  42:          /// </summary>
  43:          public void StartTransaction()
  44:          {
  45:              throw new NotImplementedException();
  46:          }
  47:   
  48:          /// <summary>
  49:          /// Rolls back a transation.  Not implemented now but will be later.
  50:          /// </summary>
  51:          public void RollbackTransaction()
  52:          {
  53:              throw new NotImplementedException();
  54:          }
  55:      }

That’s pretty much it for our data layer for now.  No we’ll do a couple things in our Business Layer.  We’ll start by adding a new folder named “Screens”.  To that folder we’ll add a new class named “ScreenBase”.  For all of our views (to be created later) we’ll create a strongly typed Screen that we’ll tie to that view. Our ScreenBase is going to be an abstract class that will contain an instance of our repository class (so all of our child Screens will have access to it) and a few abstract properties and methods:

   1:  public abstract class ScreenBase
   2:      {
   3:          protected VeritasRepository repo = VeritasRepository.GetInstance();
   4:   
   5:          public ScreenBase()  {  }
   6:   
   7:          /// <summary>
   8:          /// Determines if the entites associated with the view 
   9:          /// are valid or not.
  10:          /// </summary>
  11:          public abstract bool IsValid { get; }
  12:   
  13:          /// <summary>
  14:          /// Loads up whatever entities this screen may need.
  15:          /// </summary>
  16:          protected abstract void LoadScreen();        
  17:      }

The last thing we’ll create today are some base objects in our UI project.  Specifically we’ll create a Form class (to override some of the functionality of the html helpers) and some overrides of the ViewPages, ViewUserControl, and ViewMasterPage.  We’ll start by adding a new class named “VeritasForm” to the Views folder:

   1:  public class VeritasForm
   2:      {
   3:          private VeritasRepository repo = VeritasRepository.GetInstance();
   4:          internal const string CACHE_KEY = "_VeritasForm_Cache_Key";
   5:          internal HtmlHelper Helper { get; set; }
   6:   
   7:          /// <summary>
   8:          /// Our static accessor so we can easily access this from the views.
   9:          /// </summary>
  10:          /// <param name="helper"></param>
  11:          /// <returns></returns>
  12:          public static VeritasForm GetInstance(HtmlHelper helper)
  13:          {
  14:              if (helper.ViewContext.HttpContext.Items.Contains(CACHE_KEY))
  15:                  return (VeritasForm)helper.ViewContext.HttpContext.Items[CACHE_KEY];
  16:              VeritasForm form = new VeritasForm(helper);
  17:              helper.ViewContext.HttpContext.Items.Add(CACHE_KEY, form);
  18:              return form;
  19:          }
  20:         
  21:          private VeritasForm(HtmlHelper helper)
  22:          {
  23:              Helper = helper;
  24:          }
  25:      }

Later on we’ll put overrides on helper methods like ActionLink, DropdownList, and more here.  Moving along, we’ll override the ViewMasterPage and create the “VeritasViewMasterPage”:

   1:  public class VeritasViewMasterPage : ViewMasterPage
   2:      {
   3:          public VeritasForm VeritasForm
   4:          {
   5:              get
   6:              {
   7:                  return VeritasForm.GetInstance(Html);
   8:              }
   9:          }
  10:      }

We’re just adding the VeritasForm as a member of our overridden Master Page.   The reason for this is so that later on when we have master pages, we’ll change what they inherit to the VeritasViewMasterPage and we’ll have easy access to VeritasForm.  We’re going to do the same thing for the ViewPage and the ViewUserControl, though one thing to note is that for both of these, we have to override both the version that takes in a templated type and the version that does not.

   1:  public class VeritasViewPage<T> : ViewPage<T> where T : class
   2:      {
   3:          public VeritasForm VeritasForm
   4:          {
   5:              get
   6:              {
   7:                  return VeritasForm.GetInstance(Html);
   8:              }
   9:          }
  10:      }
  11:   
  12:      public class VeritasViewPage : ViewPage
  13:      {
  14:          public VeritasForm VeritasForm
  15:          {
  16:              get
  17:              {
  18:                  return VeritasForm.GetInstance(Html);
  19:              }
  20:          }
  21:      }

And here’s the VeritasViewUserControl:

   1:  public class VeritasViewUserControl<T> : ViewUserControl<T> where T : class
   2:      {
   3:          public VeritasForm VeritasForm
   4:          {
   5:              get
   6:              {
   7:                  return VeritasForm.GetInstance(Html);
   8:              }
   9:          }
  10:      }
  11:   
  12:      public class VeritasViewUserControl : ViewUserControl
  13:      {
  14:          public VeritasForm VeritasForm
  15:          {
  16:              get
  17:              {
  18:                  return VeritasForm.GetInstance(Html);
  19:              }
  20:          }
  21:      }

Now, you might be wondering why we haven’t gone over any tests?  Well unfortunately, most of the things we’ve done require us to do some mocking.  Specifically, we need to be able to mock the ViewContext.  Since we’re not ready to go over that yet, we won’t go over the tests for these methods (yet).  The tests are there, we’re just not implementing them.  You can download the latest here.

Chris Risner