Showing posts with label Patterns. Show all posts
Showing posts with label Patterns. Show all posts

Sunday, February 19, 2012

Simple Circles–NHibernate Unit Testing (Part 7c)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.

In Part 7a I implemented the Repository pattern using NHibernate and in Part 7b I used Fluent NHibernate to implement the Data Mapper pattern between the domain layer and the relational database layer. In this post I’ll build unit tests to exercise these implementations.

One of the problems with attempting to test a data access strategy is ensuring the database is in a known state at the start of each test. Previously I’ve used teardown and setup SQL scripts to empty out data and preload initial values in a database instance. That approach is tedious because it means maintaining two sets of scripts in a different syntax (SQL instead of C#) and using a different toolset (SSMS). Another approach that’s becoming more popular and prevalent is to use a lighter footprint database engine capable of running in-memory. In fact, Fluent NHibernate makes this easy with its standard configuration – all it takes is setting up an NHibernate session configured to use the in-memory database as shown here:

SessionFactory Class
namespace Circles.NHibernateTests
{
  using Circles.NHibernateRepository;

  using FluentNHibernate.Cfg;
  using FluentNHibernate.Cfg.Db;

  using NHibernate;
  using NHibernate.Cfg;
  using NHibernate.Tool.hbm2ddl;

  public class SessionFactory
  {
    private static Configuration staticConfig;

    public static ISessionFactory CreateSessionFactory()
    {
      return
        Fluently.Configure()
          .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
          .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PartyRepository>().ExportTo(System.Console.Out))
          .ExposeConfiguration((c) => staticConfig = c)
          .BuildSessionFactory();
    }

    public static void BuildSchema(ISession session)
    {
      var export = new SchemaExport(staticConfig);
      export.Execute(script: true, export: true, justDrop: false, connection: session.Connection, exportOutput: null);
    }
  }
}
Lines 20-22 contain all the “magic”: line 20 configures the database to use the standard in-memory configuration for SQLite. Line 21 sets up the mappings to be read from the PartyRepository assembly; in addition, the ExportTo() method call will dump the generated hbm.xml to the console. Line 22 exposes the configuration being set up before it is passed to NHibernate for session creation. In this case, the Lambda expression stores the newly built configuration in a static variable for later reuse by the BuildSchema method.

xUnit does not implement or use constructs such as [Setup] / [Teardown] like nUnit does or [TestInitialize] / [TestCleanup] like MSTest does since the authors feel it is problematic. You can read more about the rational on James Newkirk’s blog post “Why you should not use Setup and TearDown in NUnit”. Pretty compelling when the main author himself tells you not to; however, I’m going to bend the rules a little. I’ve implemented a base testing class that contains a virtual method called TestInitialize() whose purpose is to prepare the testing database and put it in a known state before each test is executed:

TestBase Class
namespace Circles.NHibernateTests
{
  using NHibernate;

  /// <summary>
  /// Base class for NHibernate / SQLite tests
  /// </summary>
  public abstract class TestBase
  {
    protected static readonly object LockObject = new object();

    private static ISessionFactory sessionFactory;

    protected ISession Session { get; set; }

    /// <summary>
    /// Code to run before the test to allocate 
    /// and configure any resources needed.
    /// </summary>
    public virtual void TestInitialize()
    {
      sessionFactory = SessionFactory.CreateSessionFactory();
      Session = sessionFactory.OpenSession();
      SessionFactory.BuildSchema(Session);
    }

    public void Dispose()
    {
      Session.Dispose();
    }
  }
}

Each test class can now easily prepare an in-memory database and place it in a known state prior to executing tests by overriding TestInitialize() with its own specific behavior:

TestInitialize() Method
public override void TestInitialize()
{
  Monitor.Enter(LockObject);

  base.TestInitialize();

  using (var tx = Session.BeginTransaction())
  {
    var householdType = new PartyType(new Guid(Constants.PartyTypeIdHousehold))
    {
      TypeName = "Household"
    };
    Session.Save(householdType);

    var personType = new PartyType(new Guid(Constants.PartyTypeIdPerson))
    {
      TypeName = "Person"
    };
    Session.Save(personType);

    var person = new Person
    {
      FirstName = "Nancy",
      LastName = "Davolio",
      Gender = GenderEnum.Female,
      Birthday = new DateTime(1948, 12, 8),
      PartyType = personType
    };
    Session.Save(person);

    Session.Flush();
    tx.Commit();
  }

  Session.Clear();

  Monitor.Exit(LockObject);
}

The Monitor.Enter and Monitor.Exit calls (lines 3 & 38) ensure that access to the NHibernate Session remains serialized and two test methods can’t accidently interfere with each other in multi-threaded harnesses. The first call is to the base class’ implementation which creates the in-memory database. Following that I create PartyType instances for Household and Person and then create and persist a well-known Person instance.

With the base class and SessionFactory implemented and in place, constructing unit tests that can exercise (indirectly) the mappings as well as an actual, deployed database layer becomes trivial:

CanAddHousehold() Test Method
[Fact]
public void CanAddHousehold()
{
  this.TestInitialize();

  IPartyRepository repository;
  Household household;

  // arrange
  using (var tx = Session.BeginTransaction())
  {
    repository = new PartyRepository(Session);
    var partyType = repository.FindPartyTypeById(new Guid(Constants.PartyTypeIdHousehold));

    // act
    household = new Household
    {
      PartyName = "Eisenhower",
      FormalGreeting = "President Dwight D. and Mrs. Mamie",
      InformalGreeting = "Ike and Mamie",
      PartyType = partyType
    };

    repository.Add(household);
    tx.Commit();
  }

  // assert
  Assert.NotNull(household);
  Assert.NotNull(repository.FindById(household.PartyId));
}

Line 4 initializes the database including preparing the known state, Line 12 initializes a PartyRepository instance using the in-memory database session. This particular line of code deserves special attention – I’m creating a PartyRepository and giving it the in-memory database to operate against. Recall in Part 7a on Line 47 of the fourth code fragment (DBSession class)  that a PartyRepository instance was created using the “real” NHibernate DbSession there. Here’s where designing the NHibernate repository to accept an ISession implementation gives flexibility.

Line 13 retrieves the household party type that is known to be there because it was created and saved during TestInitialize(). Finally the household is created and saved. An interesting side effect of this test was when I first ran it – it failed. I had forgotten to specify/assign a PartyType to the household instance. When I referred back to the earlier tests that I put together using the FakeRepository I realized that it too wasn’t assigning or checking the party type. This oversight illustrates a problem with trying to fake or mock an implementation – you have to remember to code and test all the validation and business rules necessary to be a “real” repository. This is the best reason to have taken these steps of setting up a reusable, fast way to test the real repository – as you code the repository, you can test it without having to write double the code by updating the fake one.

This discovery led to adding a negative test to ensure the repository doesn’t allow a household without a party type:

Negative Test
[Fact]
public void CanNotAddHouseholdWithMissingPartyType()
{
  this.TestInitialize();

  // arrange
  using (var tx = Session.BeginTransaction())
  {
    var repository = new PartyRepository(Session);

    // act
    var household = new Household
    {
      PartyName = "Eisenhower",
      FormalGreeting = "President Dwight D. and Mrs. Mamie",
      InformalGreeting = "Ike and Mamie",
      /* PartyType = partyType */
    };

    // assert
    Assert.Throws<NHibernate.PropertyValueException>(
      delegate
      {
        repository.Add(household);
      });

    tx.Rollback();
  }
}

Lines 21-25 uses the xUnit Assert.Throws<> method to wrap the attempt to add a household without a party type. If the repository doesn’t throw an NHibernate.PropertyValueException then the test is considered to have failed.

This post was pretty densely packed with concepts - an entire framework for testing an NHibernate-based data layer. The accompanying code base is growing larger and can be downloaded from here.

Friday, February 3, 2012

Simple Circles–NHibernate Mapping (Part 7b)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.
In a previous post, I used AutoMapper to implement the DataMapper pattern to map and flatten the domain model into view models for the MVC user interface. The same approach applies to mapping the domain model to a relational database. In fact, this is the heart of an object-relational mapping (ORM) tool like NHibernate. Originally, NHibernate used XML-based mapping files similar to its Hibernate lineage. More recently, James Gregory’s Fluent NHibernate tool has emerged as a leading alternative with strengths such as supporting the fluent interface programming style, convention-based mappings, and compile-time checking (a huge time saver).
Simple Circles - Install FluentNHibernateAfter adding Fluent NHibernate v1.2.0.712 – that version is compiled against the NHibernate version I’m using – I created a \Maps folder and created the mapping classes. Before diving into the mapping, it’s time to introduce a best practice for managing concurrency and allowing detection of stale objects. By convention, NHibernate supports a special-named property called ‘Version’ that can be numeric (preferred), a timestamp or a DB timestamp. You can find more information at the NHibernate site or Ayende’s post. In the Circles data model, I’ve got a base Entity class which is a great place to put the Version property so every Entity automatically gets the benefit of optimistic concurrency checking. Here's the mappings for Party and PartyType:
namespace Circles.NHibernateRepository.Maps
{
  using Circles.Domain;

  using FluentNHibernate.Mapping;

  public class PartyMap : ClassMap<Party>
  {
    public PartyMap()
    {
      Id(x => x.PartyId).GeneratedBy.GuidComb();
      Version(x => x.Version);
      References(x => x.PartyType, "TypeId")
          .Not.Nullable();
      Map(x => x.PartyName)
          .Not.Nullable()
          .Length(255)
          .Index("ukPartyName");
    }
  }

  public class PartyTypeMap : ClassMap<PartyType>
  {
    public PartyTypeMap()
    {
      Id(x => x.TypeId).GeneratedBy.GuidComb();
      Version(x => x.Version);
      Map(x => x.TypeName)
          .Not.Nullable()
          .Length(255)
          .Index("ukTypeName");
    }
  }
}

Line #11 above maps the Id property to a column called PartyId and specifies that the Guid.Comb Identifier Strategy be used to generate new ids. Lines #12 and #13 map the referenced PartyType within a Party by creating a foreign key using TypeId as the column name.

Fluent NHibernate has the ability to not only define mappings but to configure NHibernate using the mappings along with other settings you specify. Using this ability, its also possible to export the configuration to .hbm.xml files combined with NHibernate’s ability to export .hbm files to SQL DDL. There’s a lot of power packed into the following:
namespace NHibernateSchemaExport
{
  using Circles.NHibernateRepository;

  using FluentNHibernate.Cfg;
  using FluentNHibernate.Cfg.Db;

  using NHibernate.Cfg;
  using NHibernate.Tool.hbm2ddl;

  class Program
  {
    static void Main(string[] args)
    {
      Fluently.Configure()
        .Database(SQLiteConfiguration.Standard
            .ConnectionString(c => c.FromConnectionStringWithKey("circlesdb"))
            .ShowSql)
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf()
            .ExportTo("."))
        .ExposeConfiguration(BuildSchema)
        .BuildSessionFactory();
    }

    static void BuildSchema(Configuration cfg)
    {
      new SchemaExport(cfg)
             .SetOutputFile("CirclesSchema.sql")
             .Execute(script: true, export: false, justDrop: false);
    }
  }
}

Line #18 shows the ExportTo() method being using to export the configured mappings to the current directory. Line #19 uses the ExposeConfiguration() method along with NHibernate’s SchemaExport() method on line #26 to output the database schema. These techniques give us the ability to “see into” the dynamically generated hbm and sql files.

There’s more details in the accompanying change set for this post that can be downloaded here. Next up is implementing the PartyRepository now that NHibernate is configured and the domain-to-database mapping is coming together.

Thursday, January 19, 2012

Simple Circles–MVC Controller Unit Tests (Part 5)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.

Simple Circles - ControllerTestsIn the last post I left off with the PeopleController refactored to use an IPartyRepository via dependency injection. Now I’ll create unit tests for the controller so that we’ll know if something breaks as the solution evolves. Since I’m planning on several views and controllers, I added a ControllerTests folder to the UnitTests project to organize and group them together. With xUnit, as with many unit testing frameworks, simply add a new class called PeopleControllerTest and begin writing the tests.

Unit testing MVC controllers generally falls into two categories:
  1. Ensuring that an action result being returned from a controller’s action is correct. On HTTP GET requests, this means the correct view result is returned.
  2. Ensuring that HTTP POSTs are behaving properly:
    1. A POST with purposely invalid model data causes it to route the request back to the originating view.
    2. A POST with correct model data causes it to route back to the Index view.
Because of the dependency injection work just done, setting up the unit test is straightforward:
[Fact]
public void DefaultGetReturnsIndexView()
{
// arrange
const string ExpectedViewName = "Index";
var peopleController =
new PeopleController(new FakeRepository.FakePartyRepository());

// act
var viewResult = peopleController.Index();

// assert
Assert.NotNull(viewResult);
Assert.Equal(ExpectedViewName, viewResult.ViewName);
var model = viewResult.ViewData.Model as IEnumerable;
Assert.NotNull(model);
}

Notice on Line #6 above that it’s easy to pass a new instance of the FakeRepository from the test method. The assertions section checks that a view result was returned, that it was the expected named view result and that the view’s model is present.


Testing the HTTP POST actions is a bit more involved. The basic test is the same however since the testing class is calling the controller directly a little more work is needed. Model validation is a part of the MVC runtime which is not present during testing so it is necessary to “prime the pump” so to speak by placing the error into the controller’s ModelState to see if it’s being handled correctly – this is essentially the same behavior the MVC runtime exhibits:

[Fact]
public void CreatePostReturnsViewIfModelStateIsInvalid()
{
// arrange
const string ExpectedViewName = "Create";
var peopleController
= new PeopleController(new FakeRepository.FakePartyRepository());
peopleController.ModelState.AddModelError("LastName", "LastName is required.");
var person = new Person
{
FirstName = "Henry",
MiddleName = "Lewis",
//LastName = "Stimson ",
Gender = Enum.GetName(typeof(GenderEnum), GenderEnum.Male),
Birthday = new DateTime(1867, 9, 21)
};

// act
var viewResult = peopleController.Create(person) as ViewResult;

// assert
Assert.NotNull(viewResult);
Assert.Equal(ExpectedViewName, viewResult.ViewName);
}

Line #8 above is where the error is set up. Lines #9 through #16 create a Person instance to pass to the controller method to mimic what the MVC runtime will do. Notice that I commented out the line for setting the LastName property for authenticity purposes. Personally, I would hate to come across some else’s code that sets up an error yet passes in perfectly valid data. Finally, the assert statements check that the same Create view is returned indicating that the error(s) were detected and handled properly.

Testing for a valid model is nearly the same – just don’t set the ModelState, pass a valid Person instance and check that we’re returned to the Index page. Edit, update and delete actions are nearly identical as well.


The final bit of code worthy of mention is around the use of AutoMapper – remember that the last post introduced AutoMapper as an implementation of the DataMapper pattern. I wired up the mapping initialization inside Global.asax.cs then. Of course the test harness doesn’t have a website since it’s job is exercising the logic and behavior of the controller classes. Therefore I have to use the xUnit way of introducing a “fixture” necessary for the test class to operate.

public class PeopleControllerTest : IUseFixture<DataMapperFixture>
{
public void SetFixture(DataMapperFixture data)
{
data.CreateMaps();
}
...
}
...
public class DataMapperFixture : IDisposable
{
public void CreateMaps()
{
Mapper.AssertConfigurationIsValid();
PersonMap.CreateMaps();
}
}

The test class implements the xUnit IUseFixture<T> interface which tells the xUnit runtime that it needs to call SetFixture with an instance of that type – in my case I created a trivial DataMapperFixture class that simply verifies the mapping is valid and calls the PersonMap.CreateMaps() method to initialize AutoMapper.


The source code for this article can be downloaded from here. The next installment will explore some simple jQuery enhancements to make the UI a little nicer and more informative.

Sunday, January 15, 2012

Simple Circles–Add an ASP.NET MVC 3 UI (Part 4b)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.
Simple Circles - Ninject packageIn the last post I left off with a scaffolded People MVC implementation that was hard-wired to use the Entity Framework 4 data access technology. In this post I’m going to replace that with the Ninject dependency-injection framework and use the previously built FakePartyRepository implementation to begin testing the UI quickly.
With NuGet, adding Ninject support is easy – just two simple commands: ‘Install-Package Ninject -Version 2.2.1.4’ and ‘Install-Package Ninject.MVC3 -Version 2.2.2.0’. I chose to include specific versions since they were specified on the corresponding NuGet Gallery pages. Once again there is a lot going on behind the scene as shown to the right.
Simple Circles - Ninject.MVC3The Ninject.MVC3 extension was created to add support to MVC 3 applications including DI for Controllers, filters, validators and the Unit of Work pattern for NHibernate (more on this later!). The NuGet version adds a class to the \App_Start folder called NinjectMVC3 wired and ready to go. It does so by hooking in with the WebActivator project – one of the dependencies automatically installed when the Ninject.MVC3 package was installed.

Controller

First I’ll add references to the Domain and Persistence projects to bring in their type definitions then I’ll replace the EF context reference in PeopleController with the IPartyRepository instead. Refer to the last screenshot in the previous post to see the boilerplate code generated by the scaffolding.
public class PeopleController : Controller
{
  private readonly IPartyRepository repository;

  public PeopleController(IPartyRepository repository)
  {
    this.repository = repository;
  }

  public ViewResult Index()
  {
    IEnumerable<Domain.Person> persons = this.repository.FindAllPersons();
    return View(persons);
  }
  ...

The problem with the above code is that it will not compile because of line 13 – ‘return View(persons)’. The MVC convention is to use separate model classes in the presentation layer to decouple it from the business/domain layer. I did exactly this when creating a Person class in the \Models folder - essentially flattening the EntityBase->Entity->Party->Person inheritance hierarchy to just Person. The scaffolding constructed the views (Index, Details, Edit, etc.) to work with the Models.Person class – not the Domain.Person. Line 12 is returning an enumeration of Domain.Person instances whereas the view expects Models.Person instances.

Data Mapper


The solution to this mismatch lies in another tool called AutoMapper which makes using the Data Mapper pattern a cinch. Jeremy Miller’s MSDN article Persistence Patterns gives a good overview of how these various proven patterns fit and work together. Also, Jimmy Bogard wrote a series of articles on his tool at Los Techies. Back to the NuGet Package Manager console to ‘Install-Package AutoMapper’.

I created a \Maps folder and added a new class called PersonMap to define the mapping back and forth between the two models…
internal class PersonMap
{
  internal static void CreateMaps()
  {
    Mapper.CreateMap<Domain.Person, Models.Person>()
        .ForMember(dest => dest.Birthday, opt => opt.MapFrom(src => src.Birthday))
        .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
      ...
        .ForMember(dest => dest.PersonId, opt => opt.MapFrom(src => src.PartyId))
        .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.PartyName))
        .ForMember(dest => dest.Salutation, opt => opt.MapFrom(src => src.Salutation ?? null))
        .ForMember(dest => dest.Suffix, opt => opt.MapFrom(src => src.Suffix ?? null));

    Mapper.CreateMap<Models.Person, Domain.Person>()
        .ForMember(dest => dest.ChannelAddresses, opt => opt.Ignore())
        .ForMember(dest => dest.Birthday, opt => opt.MapFrom(src => src.Birthday))
        .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
      ...
        .ForMember(dest => dest.PartyId, opt => opt.MapFrom(src => src.PersonId))
        .ForMember(dest => dest.PartyName, opt => opt.Ignore())
        .ForMember(dest => dest.PartyType, opt => opt.Ignore())
        .ForMember(dest => dest.PostalAddresses, opt => opt.Ignore())
        .ForMember(dest => dest.Salutation, opt => opt.MapFrom(src => src.Salutation ?? null))
        .ForMember(dest => dest.Suffix, opt => opt.MapFrom(src => src.Suffix ?? null));
  }
}
A few things are worth pointing out in the above listing:

  1. Line #9 shows how I map the generic, internal PartyId from the domain model to the more friendly and meaningful PersonId in the MVC layer.
  2. Line #10 does the same for the PartyName - mapping it to a FullName property.
  3. Line #15 tells the mapper to ignore the ChannelAddress property in the domain model – it will not be mapped to the MVC layer. The same goes for PostalAddresses  –  these will be dealt with later and in a manner appropriate for the user interface.
  4. Lines #11, #12, #23, #24 show how optional fields are handled.

A call to PersonMap.CreateMaps() in Global.asax.cs will initialize the maps when the website starts up. To use the maps, add a line to invoke the data mapping like this:
[HttpPost]
public ActionResult Create(Person person)
{
  if (!ModelState.IsValid)
  {
    return View(person);
  }

  var entity = Mapper.Map<Person, Domain.Person>(person);

  this.repository.Add(entity);

  return RedirectToAction("Index");
}

Line #9 is the magic – transferring the contents of the MVC Models.Person to the Domain.Person before passing to the repository to store.

Dependency Injection


The PeopleController at the top of this article used constructor injection on Line #5 to receive an IPartyRepository instance. Following the Ninject samples and documentation, I’ve added a \Services\ServicesModule which inherits from NinjectModule to handle the injection of services:
/// <summary>
/// A Ninject module to bind services.
/// </summary>
public class ServicesModule : NinjectModule
{
  /// <summary>
  /// Called when the module loads into the kernel.
  /// </summary>
  public override void Load()
  {
    this.Bind<IPartyRepository>()
        .To<FakePartyRepository>()
        .InRequestScope();
  }
}

To wire up the module, add a line to the RegisterServices method found in NinjectMVC3:
private static void RegisterServices(IKernel kernel)
{
  kernel.Load<Services.ServicesModule>();
}

The end result of this effort is that I can now browse and display the list of persons as shown here:

Simple Circles - MVC with Fake Repo

Next time I’ll set up a unit test to exercise the functionality of the controller through injection so that I won’t have to always manually hit every view/page to see if it still works as changes are made.

The source code for this article can be downloaded from here.

Monday, January 9, 2012

Simple Circles–Fake Repository (Part 3)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc. With a basic structure for the domain objects taking shape it’s time to move on to the notion of persistence.

In the last post I set up the interfaces to support the Repository pattern and left off with the following signature:

namespace Circles.Persistence
{
using System;
using System.Linq;

public interface IPartyRepository : IRepository<Party, Guid>, ISupportSave<Party, Guid>, ISupportDelete<Party, Guid>
{
IQueryable<Household> FindAllHouseholds();
IQueryable<Organization> FindAllOrganizations();
IQueryable<Person> FindAllPersons();
}

Now I’m going to put together a simple fake repository implementation to exercise the interfaces as well as quickly provide sample data to work with. I’ve added a new project called FakeRepository containing a single class called FakePartyRepository partly shown here:

namespace Circles.FakeRepository
{
using System;
using System.Collections.Generic;
using System.Linq;

public class FakePartyRepository : IPartyRepository
{
private readonly List<Household> fakeHouseholdList = new List<Household>
{
new Household { PartyName = "Churchill", FormalGreeting = "Sir Winston and Lady Clementine" },
new Household { PartyName = "Roosevelt", FormalGreeting = "President Franklin and Mrs. Eleanor" },
};

private readonly List<Organization> fakeOrganizationList = new List<Organization>
{
new Organization { PartyName = "Great Lakes Food Market" },
new Organization { PartyName = "Hungry Coyote Import Store" },
new Organization { PartyName = "Lazy K Kountry Store" },
};

private readonly List<Person> fakePersonList = new List<Person>
{
new Person { FirstName = "Nancy", LastName = "Davolio", Gender = GenderEnum.Female, Birthday = new DateTime(1948, 12, 8) },
new Person { FirstName = "Andrew", LastName = "Fuller", Gender = GenderEnum.Male, Birthday = new DateTime(1992, 8, 14) },
};

private readonly IQueryable<Household> fakeHouseholdRepository;
private readonly IQueryable<Organization> fakeOrganizationRepository;
private readonly IQueryable<Person> fakePersonRepository;
private readonly IQueryable<Party> fakePartyRepository;

public FakePartyRepository()
{
this.fakeHouseholdRepository = this.fakeHouseholdList.AsQueryable();
this.fakeOrganizationRepository = this.fakeOrganizationList.AsQueryable();
this.fakePersonRepository = this.fakePersonList.AsQueryable();
this.fakePartyRepository = this.fakeOrganizationList.Union(this.fakePersonList).Union(this.fakeHouseholdList).AsQueryable();
}

public IQueryable<Party> FindAll()
{
return this.fakePartyRepository;
}

public Party FindById(Guid id)
{
return this.fakePartyRepository.FirstOrDefault(x => x.PartyId == id);
}
}

As you can see, the underlying data is contained in simple in-memory generic Lists that are wrapped into LINQ IQueryable objects. Note the last line of the constructor where the fakePartyRepository is a .Union of the three underlying lists.


Simple Circles - xunitTo test the FakeRepository let’s add another class library project called UnitTests. We’ll use NuGet to add the xUnit package with the command ‘install-package xunit’ as shown to the right. xUnit was created by James Newkirk (creator of the venerable NUnit) and Brad Wilson to better reflect the purpose of driving and iterating the design of an implementation at the unit level. Brad discusses this philosophy in his article Its not TDD, It’s Design by Example. After adding the xUnit reference, add a class called PartyRepositoryTest:

  public class PartyRepositoryTest
{
[Fact]
public void CanAddHousehold()
{
// arrange
IPartyRepository repository = new FakePartyRepository();

// act
var id = repository.Add(new Household
{
PartyName = "Eisenhower",
FormalGreeting = "President Dwight D. and Mrs. Mamie",
InformalGreeting = "Ike and Mamie"
});

// assert
Assert.NotNull(id);
Assert.NotNull(repository.FindById(id));
}
}

The first thing you may notice is that xUnit uses the attribute [Fact] rather than [Test] as other TDD frameworks do. As Brad puts it “a [Fact] is an expression of some condition which is invariant”. Essentially we’re saying that the condition “CanAddHousehold” is an invariant condition of the PartyRepository which must always be true. In addition to expressing facts, xUnit lets you express theories which are “an expression of a condition which is only necessarily true for the given set of data.”:

  [Theory,
InlineData("D28AA45E-C650-4121-8070-3D12BE31F91A")]
public void CanFindSinglePerson(string id)
{
// arrange
IPartyRepository repository = new FakePartyRepository();
var partyId = new Guid(id);

// act
var person = repository.FindById(partyId) as Person;

// assert
Assert.NotNull(person);
Assert.True(person.Id == partyId);
}

Simple Circles - Unit TestsSince we built the FakeRepository with our known data, we can construct tests with known values to prove the repository is working as designed without defects. In the above example, we know the PartyId of one of the person instances that we put into the fake repository so we can attempt to retrieve that person to exercise that logic. ReSharper’s test runner shows all the tests we currently have. Before the tests can be compiled and run, you must add a reference to the Extensions subproject of xUnit which holds the [Theory] attribute definition and behavior. Once again, use the NuGet Package Manager Console to execute the command “install-package xunit.extensions”.


Finally, you’ll notice in the above samples as well as the source code accompanying this post that I’ve followed the “3A” or “Arrange-Act-Assert” principle for writing the tests.


The source code for this article can be downloaded from here.


Next we’ll look at starting an ASP.NET MVC 3 website to consume and present the domain model.

Wednesday, January 4, 2012

Simple Circles–Persistence (Part 2)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc. With a basic structure for the domain objects taking shape it’s time to move on to the notion of persistence.
One of the tenets of DDD is known as “aggregate root” – a top-level, course grained collection of responsibilities. In plain object-oriented systems, objects tend to expose granular methods to operate on their data. Unfortunately, this approach allows business knowledge and intimate design details to creep outside of the model. That is, accomplishing a business operation usually entails making several method calls across several objects – this sequencing of calls becomes embedded externally in calling applications making the whole thing tightly coupled and brittle. The aggregate root principle groups related objects closely and provides consistent and coordinated access to these related objects.Vaughn Vernon wrote an in depth three-part article on the topic of Effective Aggregate Design.
In this model the Party is an obvious root object – we don’t access addresses or notes without first going through the Party instance they belong to. This approach leads to methods like Party.AddAddress() or Party.AddNote() rather than creating addresses and notes separately.
Once the aggregate root(s) have been identified it’s time to move on to persisting the data they contain. The Repository pattern is a proven way to implement persistence in a storage-neutral manner. There are many references to consult for more information but in the context of DDD, Jak Charlton’s post, DDD: The Repository Pattern, is particularly concise and a good starting point for why it is useful. Gabriel Schenker provides another good write up with code examples on the NHibernate FAQ. Given that we have a Party aggregate root, we should also have a PartyRepository since each aggregate should be responsible for its own “domain” or “scope” if you will.
Since repositories manage aggregate roots and their associated entities/ values, the basic semantics for the repository follow that of a generic collection. For us this means something like:
namespace Circles.Persistence
{
  using System;
  using System.Collections.Generic;

  public interface IPartyRepository
  {
    IList<Party> FindAllParties();
    Party FindPartyById(Guid Id);
    Guid Add(Party party);
    void Delete(Guid Id);
    void Update(Party party);
  }
}

Some might balk at the Delete and Update methods, arguing that pure collections have “Remove” instead. However, I am of the opinion that we’re working with domain (a.k.a. business) entities that are persisted somewhere so the semantics of persisting data are more natural with delete and update.

Of course the above approach is very "party-specific” so it could be refactored using generics like this:
namespace Circles.Persistence
{
  using System;
  using System.Collections.Generic;

  public interface IRepository<T> where T : Entity
  {
    IList<T> FindAll();
    T FindById(Guid Id);
    Guid Add(T entity);
    void Delete(Guid Id);
    void Update(T entity);
  }
}

Now we’ve got an interface that supports any type of domain entity – note the removal of the term “Party” from the method names.

The above refactored interface implies that every repository created supports all four “CRUD” operations.  A better approach would be to split out the operations and then have a specific repository implement the ones it needs like this:
namespace Circles.Persistence
{
  using System;
  using System.Linq;

  public interface IRepository<T, in TId> where T : Entity
  {
    T this[TId id] { get; set; }
    IQueryable<T> FindAll();
    T FindById(TId Id);
  }

  public interface ISupportSave<in T, out TId> where T : Entity
  {
    TId Add(T entity);
    void Update(T entity);
  }

  public interface ISupportDelete<T, in TId> where T : Entity
  {
    void Delete(TId Id);
  }

  public interface IPartyRepository : IRepository<Party, Guid>, ISupportSave<Party, Guid>, ISupportDelete<Party, Guid>
  {
    IQueryable<Household> FindAllHouseholds();
    IQueryable<Organization> FindAllOrganizations();
    IQueryable<Person> FindAllPersons();
  }

Now we’re explicit about what the PartyRepository does. By implementing IRepository, ISupportSave and ISupportDelete we’re clear that the IPartyRepository supports full CRUD behavior using Guids for the Id types. Additionally, we provide FindAllxxx methods for retrieving specific types from the repository. Notice that having the repository return IQueryable gives flexibility on both sides – concrete implementations can translate the LINQ query passing it to the underlying data store for execution and callers can query the repository in various ways rather than being forced to go through a rigid, narrowly defined API we provide.

One more thing to cover – I slipped in a new Type called Entity that is a base class for all domain entities. Rather than rehashing all the details here I’d suggest checking out Jason Dentler’s blog or his book NHibernate 3.0 Cookbook. Equally important is Billy McCafferty’s work on Sharp Architecture. Standing on the shoulder’s of giants…

The source code for this article can be downloaded from here.

Next we’ll look at testing what we have xUnit.

Tuesday, January 3, 2012

Simple Circles–Domain Model (Part 1)

This post is part of a series on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc. Thus, it is important that the domain model be flexible enough to allow various combinations of entities to be used to support these use cases. For example, in a B2B scenario the notion of a person or a household will not likely be center stage whereas businesses will be. However, a club or sports team will likely interact with individuals and possibly households but not likely with businesses.

Models

Simple Circles - Party ConceptModeling entities such as Person, Household, and Organization come to mind immediately. However, the “Party” model has existed for many years as a way to generically model the relationships between various parties. The figure to the right illustrates graphically this concept. Person, Household, and Organization are all types of parties. This approach also allows reuse of relationships such as notes, postal addresses, and communication channels across all types of parties. Rather that duplicating logic, storage mechanisms and business rules for each entity this approach follows the Don’t Repeat Yourself (DRY) principle.

Simple Circles - Party Class DiagramTransferring the conceptual model to a physical one is accomplished using inheritance as shown in the class diagram to the right. The Party class is an abstract base class containing a PartyId unique identifier and a PartyName. Person, Household, and Organization all inherit these base properties supplementing them with specific properties they contain. Notice that the base class contains relationships to Party Note, Postal Address and Channel Address as well as to Party Type. Through inheritance all child subtypes also inherit these relationships without having to explicitly code them three different times (DRY!). Using a separate Party Type allows classifying individual party instances which supports filtering the parties in lists, views, etc.

Classes

Here is the code for the Party class which realizes the class diagram shown above:
namespace Circles.DomainModel
{
  using System;
  using System.Collections.Generic;

  /// <summary>
  /// An abstract class representing any 'Party' that can be interacted with.
  /// </summary>
  public abstract class Party
  {
    private ISet<ChannelAddress> channelAddresses = new HashSet<ChannelAddress>();
    private ISet<PartyNote> notes = new HashSet<PartyNote>();
    private ISet<PostalAddress> postalAddresses = new HashSet<PostalAddress>();

    /// <summary>
    /// Gets or sets the unique identifier of the Party instance.
    /// </summary>
    public Guid PartyId { get; set; }

    /// <summary>
    /// Gets or sets the name of the Party instance.
    /// </summary>
    public virtual string PartyName { get; set; }

    /// <summary>
    /// Gets or sets the PartyType of the Party instance.
    /// </summary>
    public virtual PartyType PartyType { get; set; }

    /// <summary>
    /// Gets or sets the Notes associated with the Party instance.
    /// </summary>
    public ISet<ChannelAddress> ChannelAddresses
    {
      get { return this.channelAddresses; }
      set { this.channelAddresses = value; }
    }

    /// <summary>
    /// Gets or sets the Notes associated with the Party instance.
    /// </summary>
    public ISet<PartyNote> Notes
    {
      get { return this.notes; }
      set { this.notes = value; }
    }

    /// <summary>
    /// Gets or sets the Notes associated with the Party instance.
    /// </summary>
    public ISet<PostalAddress> PostalAddresses
    {
      get { return this.postalAddresses; }
      set { this.postalAddresses = value; }
    }
  }
}

Note that this is not the “finished product” but rather an early version along the way. Future articles will refine this further.

The source code for this article can be downloaded from here.

Next we’ll look at persistence of this model.

Sunday, January 1, 2012

Simple Circles–Introduction

This series will be a step-by-step approach on building a simple to use web-based contact and customer relationship management application. The goals are to employ current best practices including domain-driven design (DDD), object-relational mapping (ORM), unit testing – a component of Test-Driven Development (TDD), and the model-view-controller paradigm of ASP.NET MVC3. Additionally, as the name suggests – the finished product must be simple to use. While patterns, practices and techniques employed to build the application might be advanced the end user mustn't be overwhelmed. Keeping track of a circle of friends, acquaintances and associates should be simple!
There are numerous examples of using these practices and technologies around the Internet. However many are overly simplified – designed to show a particular technique – rather than a complete “real world” example. Technical books tend to stick to the Microsoft mantra of always using their latest offering or their shiny new version of some proven OSS product. For example, Steve Sanderson’s Sports Store in Pro ASP.NET MVC 3 Framework and Tim McCarthy’s SmartCA in .NET Domain-Drive Design with C# both deliver complete examples yet neither tackle NHibernate. That is, true persistence ignorance beyond the theory that its possible. Don’t misunderstand, I’m not saying they’re bad books – I’ve bought both, used them to learn, and do refer back to them. However, if I see another contrived example of using Entity Framework with a few wizards to whip out a solution I’ll scream. Smile
This application will be built with NET 4.0 using the following tools and technologies:
  1. Visual Studio 2010 with NuGet package support
  2. ASP.NET MVC 3 and Razor view engine
  3. Persistence layer will be:
    1. NHibernate 3.1 with SQLite
    2. Entity Framework 4.1 with SQL Server CE 4.0
  4. Ninject 2.2 for dependency injection
  5. xUnit for unit testing
  6. jQuery UI for user experience.
Here are links to the posts for this project:
  1. Domain Model
  2. Persistence
  3. Fake Repository
  4. ASP.NET MVC 3 UI
    1. Scaffold People CRUD
    2. Replace EF hard wiring with Repository pattern
  5. MVC Controller Unit Tests
  6. Enabling jQuery UI
  7. NHibernate Repository
    1. IDbSession and implementation
    2. Fluent NHibernate mapping
    3. NHibernate Unit Testing
As this series is developed, I’ll keep updating this post with new links.

Sunday, March 8, 2009

.NET Adventure - Business Layer (part 2)

This post is part of a series on building a complex .NET application from scratch. In part 1 I introduced business entities and refactored code out of the data layer. Now I'm going to build out the business logic and add unit tests to support it.

NAdv14.BusinessObject.CustomerBO.ClassDiagram A new BusinessObject project (assembly) has been created and a CustomerBO class added to the project. This class contains the business logic for the customer domain entity. The class diagram for this CustomerBO is shown on the right. As the diagram indicates there are methods to get a customer instance as well as store one. In the case of GetCustomer() an instance of the Customer business entity previously described is returned with fully populated attributes. StoreCustomer() takes a Customer entity instance previously populated by a client layer and passes it to the appropriate data access object for storage.

NAdv14.BusinessObject.CustomerBO Looking at the code shown on the left, the red arrow coming in from the left side indicates where an external caller would call in to the CustomerBO class to retrieve a customer instance. The additional parameter includeAddress allows the caller to control how "deep" the retrieval goes. If only basic customer attributes are needed then setting includeAddress to false will return just the "primary" attributes. However, setting includeAddress to true will cause the customer business object to populate associated addresses by passing the customer instance to LoadAddresses. The LoadAddresses method invokes the GetAddresses method which returns the list of associated addresses and then LoadAddresses sets the customer entity's Addresses property to the result.

Since a customer address doesn't have business meaning outside of a customer I've decided not to expose a Customer Address business object. Instead, the few needed methods for manipulating the addresses have been added to the Customer business object. As the code shows, the object is "smart enough" to retrieve, set, and store associated addresses.

Notice that the Customer business entity (a.k.a.the data transfer object) is passed by the CustomerBO business object to the CustomerDAO data access object. The data access object "knows" how and where to persist the attributes of a customer, including the associated addresses. Another approach might be to have the business object, CustomerBO in this case, decompose the business entity and make decisions regarding what to store. Doing so introduces other side effects such as the business layer needing to manage transactional semantics when called upon to store information. That is, if the business object decomposes a Customer entity into its component parts - a Customer and a CustomerAddress - it will have to invoke the data access layer twice, once to store the customer and a second call to the CustomerAddressDAO to store its data. In the event of a failure, the database could be left in an indeterminate state. The usual way to handle this possibility is to wrap both calls inside a transaction. This causes the business objects to have references to and use a transaction manager. The real question is does transactional storage semantics belong up in the business layer or down in the data layer.

Now that the original data layer has been refactored we can return to the unit tests. Firstly, the DataLayer tests have been updated slightly to create instances of a Customer business entity and pass to the CustomerDAO methods. A second set of tests have been added to test the business layer. Once again, by taking the time early on to put the testing framework into place, it is reaping rewards every time we make a change to the code. We're able to exercise each layer as we go and ensure that all the moving parts line up correctly.

The code for this version of the project can be downloaded here. You'll find the new Business Object project as well as updated unit tests.

Monday, February 9, 2009

.NET Adventure - Business Layer (part 1)

This post is part of a series on building a complex.NET application from scratch. In Parts 1, 2, and 3, I introduced the data layer along with tools like NUnit, NAnt, and FxCop to round out the project development. Today I'm going to cover the first part of the entity layer.

RefAppArch Having made a first pass at the data layer in previous posts, I'm going to move up to the business layer and begin working there. Recall the Common Application Architecture diagram from Chapter 3 of Microsoft's Application Architecture Guide 2.0 shown here. Whereas the data layer used the Active Record pattern to model or "wrap" each table as a class with CRUD methods for persisting to/from the underlying table, the business layer decomposes the work into up to four separate components tailored to specific purposes.

Generally speaking, the business layer is where the domain rubber meets the binary road - that is, you typically implement the domain model and logic there. It's called the "business" layer for good reason - it's the business view of the application. While you may have normalized the data storage to 3NF such that E.F. Codd would be proud were he still here, the business view of data is typically courser grained and models business or "real world" entities. For example, in AWLT we have a Customer table and a Customer Address table which translates into two separate classes in our data layer according to the rules of the Active Record pattern. However, a business view would consider them a single Customer entity having properties of name, email address, etc. *and* one or more addresses.

NAdv.DataLayer_customer In the previous version the Data Layer defined a classic business object containing data and logic as shown on the right. Notice that there are a number of instance methods (without underlines) such as Load and Store that operate on the instance data contained within the object. However, we're going to refactor the properties out to a separate entity and make the data access object contain logic only.

The Business Entities component is where you define these entities and the Business Components is where you implement the business logic. This separation of logic and data is different from a classic business object where the data and object are encapsulated in a single class. In a layered architecture the data will need to be accessed in several places so it is usually split out into its own Business Entity component thus the Data Transfer Object pattern serves the purpose of defining entities that can be shared between parts of the system.

NAdv.BusinessEntity.Customer Notice on the left diagram there are now two classes in separate packages. First there's a new Customer class in the BusinessEntity package containing only properties (just a few are shown here). DTOs are pretty light weight - a public class with public properties that's marked as serializable. Second the data layer class formerly known as "Customer" has been refactored to CustomerDao since it is now a true data access object. The properties have been moved out and the methods are now all static since they no longer have instance data with which to work. Finally, note that several methods such as Load and Store accept a Customer instance as a parameter. Previously we would create an instance of the data layer class, set its properties and then invoke its methods to persist. Now we create an instance of the Customer entity, fill its properties and pass that instance to the Dao class to persist it.

The business entity classes can be implemented in different ways. First, they can simply be a sub folder within in a single business layer project perhaps with a separate namespace (e.g. NAdv.BusinessLayer.BusinessEntity) that is compiled into a single Business Layer assembly. The problem with this approach is that any other part of the application that needs to use a business entity (such as shown with the data layer above) must reference and have access to at runtime the business layer assembly. The further implication is that the presentation layer which "consumes" these business entities could reside on a Windows client machine and would need a copy of the business layer installed locally in order to "receive" the data from the service layer. Another way to implement business entities is to place them into their own assembly, which I've done.

The code for this version of the project can be downloaded here. You'll find the new BusinessEntity project, the refactored DataLayer project and the updated unit tests.

Friday, January 9, 2009

.NET Adventure - Data Layer (part 3)

This post is part of a series on building a complex .NET application from scratch. In Part 2, I introduced the Enterprise Library configuration and as well as unit testing with NUnit. Today I'm going to cover static code analysis using FxCop and add NAnt to the mix.

NAdv.FxCop.rules FxCop is a free tool that will analyze your code using a comprehensive set of rules grouped into nine different categories shown on the right. When I first threw together the code for this project and ran FxCop it immediately showed me all the bad habits I had - improper casing of fields vs. properties and method arguments, etc. Within a couple of minutes I had refactored things and brought the list down to just one - not having my assembly signed which I can live with for now. In fact, running it against a large project I'm involved with at my day gig turned up 450+ errors and warnings! To be fair, that project has had a lot of cooks in the kitchen and everyone has their idea of the One-True-Way™ when it comes to coding styles ;) That's the beauty of FxCop - it levels the playing field by not being emotional or stuck-in-the-mud about how things should be. The default rules it ships with are the accumulated best practices and standards employed by the Microsoft .NET engineers - talk about going straight to the source! Of course, you can edit the rules to change or disable ones you disagree with - however, my pragmatic side opted to conform so they're all on.

NAdv.FxCop.results FxCop runs as a stand alone GUI where you simply reference "target" DLLs for it to analyze - I think of them as victims which it will mercilessly rip through exposing all their weaknesses. It also ships with a command line driver called FxCopCmd if you wish to invoke it from the command line - more on that in a moment. The main window is shown on the right with my one lonely violation remaining. Step back for a moment and consider what we have...a free tool with hundreds of pre-installed rules that will analyze your code, report the results complete with detailed information about the problem so you can write better code. 'Nuff said.

So far we've got a Visual Studio project for data access and two free, open source tools to make our code better, our lives easier and reduce the federal deficit. Ok, maybe not the last one. One issue us lazy developers need to overcome is...well, being lazy. Right now, we've got to remember to run these tools. But, wait! Before you pick up that phone to call we've got one more special gift for you...

NAnt is a free .NET build tool originally based on Apache's Ant tool for Java. It uses an XML configuration file to define build projects that can be executed from the command line. Where it shines is that we can continue to develop/debug/compile in the Visual Studio IDE but when we think we're ready to go we can use NAnt to run all the steps and tools without batting an eye and both hands tied behind its back. NAnt uses the notion of targets and tasks and has...you guessed it, a bunch of tasks already set up. For our purposes, it can launch MSBuild to compile the project the same as Visual Studio does, then launch NUnit to execute all our unit tests and finally run FxCop to make sure our code is clean, polished and ready for showing off.

Since NAnt is a mature tool there's plenty of information to be found by searching around and even a good book called Expert .NET Delivery Using NAnt and CruiseControl.NET if you really want to delve in. Rather than going through the scripts line-by-line I'm going to hit the high points and techniques I use.
Organization:
  • Use a nant.cmd batch script to handle validation, setup and avoid having to remember the command line switches
  • NAdv.NAnt.invokeUse a main (or "driver") build script, called NAdv.build that sits in the solution root folder. Note that many folks like to change the default extension to .xml since it is in fact an Xml file. I prefer the default .build extension as I know instantly that it is the NAnt build script and that it is unique and special, not just some dumb old Xml file laying around in the folder tree.
  • The main build script should setup all the properties and paths then use the <nant...> task to drive individual build scripts in the project subdirectories (e.g. NAdv.DataLayer.build). This gives you cleaner organization and manageability as well as allowing each project to be tailored accordingly.
  • NAdv.NAnt.helpWithin a build script make a target called "help" AND MAKE THIS THE DEFAULT. An example output is shown on the right. <rant>I *hate* it when someone sets up an environment where you simply type in "nant" and all kinds of things start happening while the console scrolls by faster than the blink of an eye. I always think to myself "Uh-oh, what just happened. Did it build? Did it deploy and overwrite something?"</rant> It is much safer to show the help settings when someone types in "nant" and make them use an explicit build target (e.g. "nant build" or "nant deploy") - an intentional choice of what they wish to do.
  • NAdv.NAnt.execMake "main" target names a single word, e.g. clean, build, deploy, and have these targets call "internal" sub-targets that are compound words, e.g. build.init, build.compile, deploy.web, deploy.database.
  • Don't launch NUnit using NAnt's built-in <nunit2> task - use the generic <exec> task to run NUnit's console. NAnt and NUnit are different projects on different release schedules and NAnt is compiled against the version of NUnit that was available at the time it was built - NUnit 2.2.8 at the time of this writing. Using <exec> allows you to run the latest version of NUnit directly the same as when you do so interactively from the Visual Studio IDE.
One issue that comes up attempting to use the <msbuild> task to driving compiling the projects is that an Import entry is referenced incorrectly:
   1:  Change the following line in *.csproj:
   2:    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   3:  To the following:
   4:    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

Here's what the output of running "nant fxcop" looks like on the console:
NAdv.Nant.fxcop

The FxCop results can be directed to an Xml file that contains formatting which looks like this:
NAdv.FxCop.results-xml

The code for this version of the project can be downloaded from here. Note a couple of changes - the build output has been "tweaked" to NAdv_vX.X\bin which is "above" the source and test trees and the NAnt, NUnit and FxCop configurations/settings files are now included. If you unpack the zip file then open a command prompt in NAdv_vX.X (1.2 in this case) you should be able to execute "nant build, nant fxcop, and nant test" to execute all three targets. If you have problems, first check the console output and the log files and leave a comment if you're still stuck.

.NET Adventure - Data Layer (part 2)

This post is part of a series on building a complex .NET application from scratch. In Part 1, I introduced the Active Record pattern used to create data layer components. Today I'm going to wrap-up what I started by covering the Enterprise Library configuration, unit testing with NUnit and static code analysis using FxCop.
Microsoft's Enterprise Library "is a collection of reusable software components (application blocks) designed to assist software developers with common enterprise development challenges." Referring to the previous Common Application Architecture diagram, the "EntLib" would be placed on the far right as a "cross-cutting" technology. To begin with, I'm using it solely to provide low-level data access. At a minimum, you need to add a project references to the EntLib components, configure a data source and add code to use it.

For the data access references there is a standard Common library, a utility library called ObjectBuilder2, and the Data Access library:
NAdv.DataLayer_entlib.refs

Note that ObjectBuilder2 is new with version 4.x and was delivered as part of the Unity application block - more on that later. EntLib installs a custom Visual Studio designer as well as a standalone configuration editor. However, since we're using the Express Editions of Visual Studio and add-ins are not supported (hey, it's free!) the integrated designer doesn't work but we can use the standalone editor as shown here:
NAdv.EntLib_config 

Simply launch the standalone editor from the Start menu shortcut and open the configuration file. Because .NET's app.config and web.config files can become "busy" with too many options, I prefer to use the EntLib feature of storing it's configuration in a separate file called "EntLib.config" that is referenced from the app.config:
NAdv.DataLayer_app.config

Notice above that only one new section was added to app.config and in that section is the reference to the standalone EntLib configuration file - nothing else is needed there.

For completeness, here's the full EntLib.conf file as it exists at the moment:
NAdv.DataLayer_entlib.config 

To test this code we can turn to NUnit. Again, I'll say the goal of this series isn't to drill so deeply in one technology but rather to pull together various technologies into an end-to-end working application. Marc Clifton wrote a series of articles on Unit Test Patterns that is a good introduction to just how far one can go in designing and preparing tests. Suffice to say that this is a topic unto itself and that the tests I've shown are far from complete - more along the lines of simple black-box pass/fail tests. My goal was to lay the groundwork for testing the data layer and show how the layered architecture lends itself to this kind of quality, professional development that delivers resilient code. Using a testing framework/harness and some code you can immediately exercise the layer with relatively little effort.

NAdv.UnitTests.referencesSince NUnit is a test harness or "driver application" that runs tests, you simply need to create standard .NET class libraries with classes that publicly expose the tests you wish to make available. As a starting point, you should at least write a test for each publicly exposed method that can be called externally. The testing assembly needs a reference to the NUnit.Framework assembly as well as your own projects that you'll be testing as shown here on the right.

You'll notice that I've also created an app.config and EntLib.config file here in the unit test assembly. While testing code, this assembly will be the controlling application so any references to configuration data will be found here in this project and not in the "lower-level" project being tested - the NAdv.DataLayer in this example. In fact, the configuration examples shown above were actually from the UnitTests project and not the DataLayer project!

Here's some simple code to test adding a new customer:
[TestFixture]
  public class CustomerTest
  {
    [Test]
    public void AddCustomer()
    {
      Customer customer = new Customer();
      SetCustomerValues(customer);
      int customerId = customer.Store();
    }

    ... <snip> ...
     
    private void SetCustomerValues(Customer customer)
    {
       string timestamp = DateTime.Now.Ticks.ToString();

       customer.CompanyName = "AdventureWorks Unit Test " + timestamp;
       customer.EmailAddress = timestamp + "@adventureworks.com";
       customer.FirstName = "Unit";
       customer.LastName = "Test";
       customer.MiddleName = "A.";
       customer.NameStyle = NameStyleValue.Western;
       customer.PasswordHash = "L/Rlwxzp4w7RWmEgXX+/A7cXaePEPcp+KwQhl2fJL7w=";
       customer.PasswordSalt = "1KjXYs4=";
       customer.Phone = "1234567890";
       customer.Salesperson = "Salesperson " + timestamp;
       customer.Suffix = "Jr.";
       customer.Title = "Mr.";
    }
  }

The [TestFixture] and [Test] attributes are NUnit's way of marking a class and method, respectively, to indicate that they are test code which it should execute. The AddCustomer() method is public, accepts no parameters and returns nothing to the caller (NUnit). The essence of the test is to construct an instance of the Customer class, set all the properties, and call the Store() method. While this is a contrived, hard-coded example it does show how little effort it takes to begin writing unit tests.

Because we're using the Express Editions of Visual Studio, some functionality is limited including the ability to configure custom debugging settings. In fact, the default installation shows a "basic" set of configuration settings on a project. You must use Tools | Options on the VS menu then select "Projects and Solutions" and check the "Show advanced build configurations" to be able to switch from Release to Debug builds or see additional project configuration options. Even after doing this you won't be able to specify the NUnit GUI as the application to launch when debugging. However, if you add the following two lines to the *.csproj file for your unit test project:
<StartAction>Program</StartAction>
<StartProgram>C:\NUnit 2.4.8\bin\nunit.exe</StartProgram>
within the <PropertyGroup> for the Debug configuration you'll be able to press 'F5' to start debugging and the NUnit GUI will launch. Now, because the Visual Studio debugger has launched you can set breakpoints in your code and step through it just like the "big boys" do using Professional and Team editions.

NAdv.UnitTests.DataLayer_run

Above is the NUnit GUI showing the unit tests I've set up and run. Of course, the Zen of unit testing and TDD requires you to design your tests and APIs before ever writing a line of code - I won't lie to you and say I wrote these tests beforehand ;)

Since this post is already getting long, I don't want to set a trend so I'll stop here and discuss FxCop in the next post. The code for this version of the project can be downloaded from here.