EnterFreud -- domain object and client transaction basics

All sample code is organized as static methods of the Program class. The first and probably the simplest is EnterFreud. It creates

  • a Location instance to accommodate Dr Freud
  • a Person instance representing Dr Freud
  • a PhoneNumber instance for Dr Freud

Here is the code:

    static void EnterFreud ()
    {
      using (ClientTransaction.CreateRootTransaction ().EnterDiscardingScope ())
      {
        var loc = Location.NewObject ();
        loc.Street = "Berggasse";
        loc.Number = "19";
        loc.City = "Vienna";
        loc.Country = Country.Austria;
        loc.ZipCode = 1090;

        var person = Person.NewObject ();
        person.FirstName = "Sigmund";
        person.Surname = "Freud";
        person.Location = loc;

        var pn = PhoneNumber.NewObject ();
        pn.CountryCode = "0043";
        pn.AreaCode = "1";
        pn.Number = "3191596";
        pn.Person = person;

        ClientTransaction.Current.Commit ();
      }
    }

The most interesting parts are the ones that involve ClientTransaction. Here is the skeleton of the transaction scope providing the transaction context:

      using (ClientTransaction.CreateRootTransaction ().EnterDiscardingScope ())
      {
        // Create 'Location'
        // Create 'Person'
        // Create 'PhoneNumber'

        ClientTransaction.Current.Commit ();
      }

This code creates a root transaction, the top-level for all of the following domain object operations to happen. From this transaction, a transaction scope is put op and used in the using.

Everything that happens within the two }} {{using brackets is limited to that scope. We can create, load and modify domain objects to our heart's content within a transaction scope, all changes are gone as soon as execution passes the closing } curly brace. Unless you Commit your changes, of course, what we do in the EnterFreud sample code.

Domain objects, transaction and transaction scope conspire to ensure that

  • operations on domain objects are always limited to transaction scopes
  • transaction scopes limit the life expectancy and visibility of the transaction it belongs to
  • ClientTransaction.Current always references the transaction passed in the scope
  • domain objects have no life outside of client transactions
Rollback

As you might guess, RollBack undoes all modifications to domain objects since the last Commit. If you glue this code into EnterFreud after the ClientTransaction.Current.Commit(), you will rename Dr Freud to "Arnold", but back up from it (as evidenced by the succeeding Console.WriteLine:

        person.FirstName = "Arnold";
        Console.WriteLine (person.FirstName);
        
        ClientTransaction.Current.Rollback ();
        Console.WriteLine (person.FirstName);
Discard demo

This snippet of sample code is bogus, because it would give you an exception. It demonstrates that domain objects have no life outside transactions:

        // Throw away transaction prematurely
        ClientTransaction.Current.Discard ();
        // Access domain object -- get exception 
        // If the client transaction vanishes, the
        // domain objects in it vanish with it
        Console.WriteLine (person.FirstName);