Let business scenarios be reflected in your code

I’m working with a project where I use something I call “scenarios”. The idea is that each scenario in the businessmodel is represented by three classes.

Command – Contains the inputdata needed to perform the Scenario. Is optional since the operation might not need any input parameters.

Scenario – Validates and Executes the Command and is where the logic is kept. It is not ment to cross boundraries. It also provides an eventmodel, publishing events for Validated, Executed etc.

Result – Contains the command (input data), any exception and violations generated by the Validation- or Execution step in the scenario, as well as scenariospecific outputdata.

The reason for why I wan’t this is that I want each scenario easily detected in my coding-model. I want to be able to quickly look in the solutionexplorer in the Scenarios namespace, and directly see what the system targets in the domain. By looking at the Command- and the Result-classes I can also see what the scenario accomplishes. By isolating each scenario-flow-logic to one single class, I hopefully achieve a more cohesive and readable class.

An example

The example is not drawn from the business model since it’s about signing in to the system, hence it’s sort of an indirect business scenario, since you can’t run the “Place order scenario” if you’r not an authorized user.

The shown example is about logging in to the system and is using OpenId in an Asp.Net Mvc 2 application. This concludes two steps. First a request has to be initiated to an OpenId-provider. Second, we need to handle the callback request from the provider, hence the enum LogOnSteps. (I guess it would have been more clear to put these in two different scenarios.)

[Serializable]
public enum LogOnSteps
{
    Initiate,
    Finalize
}

The Command contains properties that are required for Step 1 as well as a flag indicating where we are in the process so that the validation and execution in the scenario-class nows what to do.

[Serializable]
public class LogOnCommand
{
    public LogOnSteps Step { get; set; }

    public string OpenId { get; set; }

    public string ReturnToUrl { get; set; }

    public LogOnCommand(LogOnSteps step)
    {
        Step = step;
    }
}

The implemented scenario extends a baseclass so that boilerplate code for catching exceptions etc. is kept away. The scenario is defined in an interface and is accessed via an IoC-container.

public class LogOnScenario : Scenario<LogOnCommand, LogOnResult>, ILogOnScenario
{
    public IOpenIdAuthenticationService AuthenticationService { protected get; set; }

    public IMembershipService MembershipService { protected get; set; }

    public LogOnScenario(
        IOpenIdAuthenticationService authenticationService,
        IMembershipService membershipService)
    {
        AuthenticationService = authenticationService;
        MembershipService = membershipService;
    }

    protected override IViolations OnValidate(LogOnCommand command)
    {
        var violations = new Violations();

        if (command.Step == LogOnSteps.Initiate)
        {
            violations.AddIf(command.OpenId.IsNullOrEmpty(), new Violation(
                ResourceStrings.LogOnCommand_OpenId_IsRequired, CommandName, "OpenId"));

            violations.AddIf(command.ReturnToUrl.IsNullOrEmpty(), new Violation(
                ResourceStrings.LogOnCommand_ReturnToUrl_IsRequired, CommandName, "ReturnToUrl"));
        }

        return violations;
    }

    protected override LogOnResult OnExecute(LogOnCommand command)
    {
        return command.Step == LogOnSteps.Initiate
            ? HandleInitiateStep(command)
            : HandleFinalizeStep(command);
    }

    private LogOnResult HandleInitiateStep(LogOnCommand command)
    {
        var logOnResult = new LogOnResult
        {
            Command = command,
            MvcActionResult = AuthenticationService
                                .InitiateMvcAuthentication(command.OpenId, command.ReturnToUrl)
        };

        return logOnResult;
    }

    private LogOnResult HandleFinalizeStep(LogOnCommand command)
    {
        var logOnResult = new LogOnResult { Command = command };
        var openIdAuthentication = AuthenticationService.AuthenticateRequest();

        if (openIdAuthentication.Violations.IsNotEmpty)
        {
            logOnResult.Violations.Add(openIdAuthentication.Violations);

            return logOnResult;
        }

        var mapper = IoCContainer.Instance.GetInstance<IObjectMapper>();
        var identity = mapper.Map<OpenIdAuthentication, Identity>(openIdAuthentication);

        logOnResult.UserSession = new UserSession(identity);
        logOnResult.Member = MembershipService.GetByOpenId(identity.OpenId);

        return logOnResult;
    }
}

Since we want every scenario to return any caught exception and violations, we have a base-class that the ScenarioResults can extend, which contains members for this.

[Serializable]
public class LogOnResult : ScenarioResult
{
    public LogOnCommand Command { get; set; }

    public ActionResult MvcActionResult { get; set; }

    public IUserSession UserSession { get; set; }

    public Member Member { get; set; }
}

Now if we take a look at some consumer code, I think it gets a bit easier to understand, and the application controller only handles logic for controlling which view and viewdata should be presented.

Step 1 – Initiate the scenario

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(LogOnViewModel viewModel)
{
    if (!ModelState.IsValid)
        return View(viewModel);

    var returnToUrl = Url.AbsoluteUrlFromAction("AuthenticateOpenIdRequest");
    var command = new LogOnCommand(LogOnSteps.Initiate)
                      {
                          OpenId = viewModel.OpenId,
                          ReturnToUrl = returnToUrl
                      };

    var scenario = IoCContainer.Instance.GetInstance<ILogOnScenario>();
    var scenarioResult = scenario.Execute(command);

    if (!scenarioResult.Succeeded)
    {
        this.HandleScenarioResult(scenarioResult);
        return View(viewModel);
    }

    return scenarioResult.MvcActionResult;
}

Step 2 – Finalize the scenario

public ActionResult Authenticate()
{
    WebUserSession.SetGuest();

    var viewModel = new LogOnViewModel(OpenIdProviders);
    var command = new LogOnCommand(LogOnSteps.Finalize);
    var scenario = IoCContainer.Instance.GetInstance<ILogOnScenario>();

    var scenarioResult = scenario.Execute(command);
    if (!scenarioResult.Succeeded)
    {
        this.HandleScenarioResult(scenarioResult);

        return View("LogOn", viewModel);
    }

    if (scenarioResult.Member == null)
        return View("SetupNewMembership");

    if (!scenarioResult.Member.IsActivated)
        return View("ConfirmMembership");

    WebUserSession.Set(scenarioResult.UserSession);

    if (WebUserSession.Current.IsAuthenticated)
        return Redirect("~/");

    return View("LogOn", viewModel);
}

That’s it.

//Daniel

HTC Desire, reboot loop

Update: No luck! The crap is sent away on maintenance.

My HTC Desire started to get stuck in a reboot loop this weekend. Tried reset to factory settings as well as updated it to v2.2 of Android. Neither helped.

This morning I fixed a new SIM card from Telia, so far no reboot. :-)

Keeping my fingers crossed.

//Daniel

EF4 – Code first CTP4

Since I’m on vacation and spend all my time on SisoDb I will not cover the new release of CTP4 for Code first and Entity framework 4, but instead direct you to a fairly nice post with good external reference links. So, instead of writing something that already has been written, go to Scott Hanselman’s blog: http://www.hanselman.com/blog/SimpleCodeFirstWithEntityFramework4MagicUnicornFeatureCTP4.aspx

I like that Microsoft has made it simpler and I really like the way you now can define your model in OnModelCreating. You can of course hook in your more detailed mappings via modelBuilder.Configurations.Add(new FooMapping());

//Daniel

Use extension methods to let your enums hold the logic.

I often stumble upon code checking values on enumerations to determine the state of some object or rule. At best, this code is extracted and put in a helper or utils class of some sort. Don’t! Use extension methods instead. It let’s you provide a name for the condition (rule) that you are checking, and it put’s it together with the enumeration.

Example
Lets say I have an enumeration with storage providers. Each provider might be able to store data virtually, hence I need the possibility of determining if it’s capable of this.

[Serializable]
public enum StorageProviders
{
    LuceneIo = 0,
    LuceneVirtual = 1
}

public static class StorageProvidersExtensions
{
    public static bool IsVirtual(this StorageProviders provider)
    {
        return provider == StorageProviders.LuceneVirtual;
    }
}

I can now act on the enumeration value it self.

...connectionInfo.ProviderType.IsVirtual()...

//Daniel

SisoDb – First code released

Recently I started playing with Lucene.Net and Json.Net for the reason of creating my own solution for persisting hierarchial-structures of data. The goal is to make it schemaless and really simple. The result was: SisoDb. As of right now it got support for:

  • Commitable Unit of work
  • Insert
  • Update
  • DeleteByKey
  • GetByKey

Roadmap

My focus in the next couple of spent hours will lie on:

  • Querying support both for Indexes as well as free text querying using Lucene
  • Version-control for concurrency detection
  • Some support for relations
  • Distrubuted proxy

Some basics

SisoDb persists Structures. The only demand that is puts on the structures being persisted is that they must have a property that contains a Guid which acts as the unique-identifier for the Structure. By conventions, this member should be named Id but you can configure this via schemas. It can be System.Nullable or System.Guid. You don’t have to provide a value, since SisoDb will generate this for you upon insert. Contained objects in the Structure should not have an Id-property. A Structure should be seen as an aggregate where contained objects and properties are leafs of data, either represented of simple value types (strings, ints, decimals, datetimes) or complex types (your own types). The Structure will be represented in the database as Json, which is produced using Newtonsofts Json.Net library. Which means, you can use the attributes of this library to affect how the structure is serialized and deserialized. As of right now there is one underlying provider, which stores the Structures (the Json, Key and Indexes) using Lucene.Net. I’m thinking of building a provider that uses MsSql as the storage media, but as of right now, it’s Lucene that is used.

An example

Create a Structure

The example model is really simple. A Customer-entity containing some simple properties for naming as well as Billing-address and Delivery-address, which is represented by a custom complex type, Address.

[Serializable]
public class Customer
{
    public Guid Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public ShoppingIndexes ShoppingIndex { get; set; }
    public DateTime CustomerSince { get; set; }
    public Address BillingAddress { get; set; }
    public Address DeliveryAddress { get; set; }

    public Customer()
    {
        ShoppingIndex = ShoppingIndexes.Level0;
        BillingAddress = new Address();
        DeliveryAddress = new Address();
    }
}

[Serializable]
public class Address
{
    public string Street { get; set; }
    public string Zip { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
}

[Serializable]
public enum ShoppingIndexes
{
    Level0 = 0,
    Level1 = 10,
    Level2 = 20,
    Level3 = 30
}

Create a Database

An instance of a SisoDatabase implementation is supposed to be long lived. It holds meta-data/schema-information about the structures being persisted. The SisoDatabase takes an IConnectionInfo which lets you define which underlying database-implementation to use as well as a connectionstring. When using the LuceneIO-provider, the connectionstring should contain the path to the directory where the data (indexes to use the correct Lucene terminology) should be stored.

var connectionInfo = new SisoConnectionInfo(StorageProviders.LuceneIo, DbPath);
var database = new SisoDatabase(connectionInfo);

This is something you would put in your IoC-container or at least in a factory.

Create a Unit-of-work & Insert a customer

The Unit-of-work is designed to be short lived. It is used for performing CRUD-operations against the database. It implements IDisposable and it’s recomended to be used in conjunction with the using-statement. If you don’t call Commit, ongoing changes aren’t flushed against the database. If you don’t use the using-statement make sure to call Dispose since it ensures that write-locks are being released.

var customer = new Customer
{
    Firstname = "Daniel",
    Lastname = "Wertheim",
    ShoppingIndex = ShoppingIndexes.Level1,
    CustomerSince = DateTime.Now,
    BillingAddress =
        {
            Street = "The street",
            Zip = "12345", City = "The City",
            Country = "Sweden"
        }
};

using (var unitOfWork = database.CreateUnitOfWork())
{
    unitOfWork.Insert(customer);
    unitOfWork.Commit();
}

Refetch and Update Customer

As of right now the only query-support is GetByKey which lets you retrieve a single item by a key-value (Guid).

using (var unitOfWork = database.CreateUnitOfWork())
{
    var customer = unitOfWork.GetByKey<Customer>(id);
    customer.ShoppingIndex = ShoppingIndexes.Level2;
    customer.Firstname = "Hans";

    unitOfWork.Update(customer);
    unitOfWork.Commit();
}

Delete Customer

As of right now you can only delete via the key-value.

using (var unitOfWork = database.CreateUnitOfWork())
{
    unitOfWork.DeleteByKey<Customer>(customer.Id);
    unitOfWork.Commit();
}

Custom key

As told, per default, you don’t have to provide any schema-information as long as the root-entity (structure) contains an Id:Guid or Id:Nullable -member. If you want to use another key-member, this is how you do it.

database.Schemas.Register<Customer>(
    builder => builder
        .SetKey(c => c.UId)
        .AddIndex(c => c.Lastname));

That’s it for now. The current code can be found here.

//Daniel

SisoDb – Some code preview

I thought I would share some code of how my SisoDb (Simple-Structure-Oriented-Db) looks like.

As of right now you have to provide info about which member contains the key. This will change and will instead be convention based.

var schemaBuilder = new ManualSchemaBuilder();
schemaBuilder.Register<Customer>(builder => builder.SetKey(c => c.Id));

You can also use SchemaBuilder.AddIndex to provide specific indexes that you wan’t to query more efficiently.

var schemaBuilder = new ManualSchemaBuilder();
schemaBuilder.Register<Customer>(
    builder => builder
        .SetKey(c => c.Id)
        .AddIndex(c => c.Lastname));

The next step is to create a database. Supported options are I/O-based or a Virtual (in-memory) database. The virtual only lasts as long as the UnitOfWork lives. The database is designed to be long-lived and is something you would keep alive, preferable using your IoC-container.

var connectionInfo = new LuceneConnectionInfo(LuceneDbTypes.Io, @"C:\#Temp\SisoDb\ConsoleSample");
var database = new LuceneDatabase(connectionInfo);

var schemas = schemaBuilder.GetSchemas();
database.RegisterSchemas(schemas);

Now we are ready to add some data, so lets create a Customer and add it using UnitOfWork

var customer = new Customer
                    {
                        Firstname = "Daniel",
                        Lastname = "Wertheim",
                        ShoppingIndex = ShoppingIndexes.Level1,
                        CustomerSince = DateTime.Now
                    };

using (var unitOfWork = database.CreateUnitOfWork())
{
    unitOfWork.Insert(customer);
    unitOfWork.Commit();
}

That’s it. If Commit() isn’t called everything is rolled back.

I will soon publish the source code on Google Code.

//Daniel

Copy paste is the first step to prevent evolution!

Stop copy pasting, not for the sake of introducing bugs but for the sake of preventing your project and yourself from evolving. I keep on stumbling on phrases like:

but that’s how we solved it in that other scenario/class

Ok, then use if for inspiration and try to reuse patterns in the previous solution, but don’t copy and paste the code. At least let your mind attack the problem again with fresh eyes and see how you have evolved from the last time you wrote a solution to a similar problem. I bet that you will come up with never and perhaps cleaner solutions.

//Daniel

Writing my own NoSql DB?

Yesterday I got a thought:

why not write something very simple that can store object-graphs without mappings and other fuss.

Yes I know there’s MongoDb, RavenDb and several others, but it’s always a great deal of fun to write something of your own. So, inspired by Ayende’s technology choices, I spent a few hours last night just fiddling around with Lucene.Net and Json.Net. The result:

A simple model

public class Address
{
    public string Street { get; set; }
    public string Zip { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
}

public class Customer
{
    [Key]
    public Guid? Id { get; set; }

    [Index]
    public string Firstname { get; set; }

    [Index]
    public string Lastname { get; set; }

    [Index]
    public int ShoppingIndex { get; set; }

    public Address BillingAddress { get; private set; }
    public Address DeliveryAddress { get; private set; }

    public Customer()
    {
        BillingAddress = new Address();
        DeliveryAddress = new Address();
    }
}

Consuming a Storage-provider

var customer = new Customer
                    {
                        Id = Guid.NewGuid(),
                        Firstname = "Daniel",
                        Lastname = "Wertheim",
                        ShoppingIndex = 99
                    };
customer.DeliveryAddress.Country = "Sweden";

var store = new LuceneStructureStore();
store.Insert(customer);

var refetched = store.GetByKey<Customer>(customer.Id.ToString());
...
...

Maybe it will grow to something useful. In the meantime I will continue my work with my MongoDB-provider, Simple-MongoDB.

//Daniel

Dealing with Enumerations and Entity framework 4 – code first

If you have an entity with an enumeration and you wan’t to store it using Entity framework 4, Code-only, you might run into problem. The convention-based mapping is sufficent for generating the schema but you will run into problem when trying to create an objectset.

The solution that I will present here is kind of simple: Make a custom-type that you map as a complex-type using ComplexTypeConfiguration, then you implement implicit operator overloading to provide implicit-conversion between this custom-type and the enumeration.

The Entity

public class Tifi : ICamyinEntity
{
    public Guid Id { get; set; }

    public byte[] Version { get; set; }

    public TifiType Type { get; set; }

    public string Title { get; set; }

    public string Description { get; set; }

    public string Source { get; set; }
}

The Enumeration

public enum TifiTypes : int
{
    Undefined = 0,
    Blog = 1,
    Video = 2
}

The Custom-type

public class TifiType
{
    public int Value { get; private set; }

    private TifiType()
        : this(default(TifiTypes))
    {}

    public TifiType(int value)
    {
        Value = value;
    }

    public TifiType(TifiTypes type)
    {
        Value = (int)type;
    }

    public static implicit operator int(TifiType type)
    {
        return type.Value;
    }

    public static implicit operator TifiType(int value)
    {
        return new TifiType(value);
    }

    public static implicit operator TifiTypes(TifiType type)
    {
        return (TifiTypes)type.Value;
    }

    public static implicit operator TifiType(TifiTypes type)
    {
        return new TifiType(type);
    }
}

The Mappings

public class TifiTypeMapping : ComplexTypeConfiguration<TifiType>, ICamyinMapping
{
    public TifiTypeMapping()
    {
        Property(o => o.Value);
    }
}

public class TifiMapping : EntityConfiguration<Tifi>, ICamyinMapping
{
    public TifiMapping()
    {
        HasKey(o => o.Id);
        Property(o => o.Id)
            .StoreGeneratedPattern = StoreGeneratedPattern.Identity;

        Property(o => o.Version)
            .IsConcurrencyToken()
            .IsRequired()
            .HasStoreType("timestamp")
            .StoreGeneratedPattern = StoreGeneratedPattern.Computed;

        Property(o => o.Source)
            .HasMaxLength(200)
            .IsUnicode()
            .IsRequired();

        Property(o => o.Title)
            .HasMaxLength(100)
            .IsUnicode();

        Property(o => o.Description)
            .HasMaxLength(1000)
            .IsUnicode()
            .IsOptional();
    }
}

That’s it. You will now be able to assign enumeration values to an instance of Tifi and it’s member Type.

var tifi = new Tifi
{
    Title = "My first Tifi",
    Description = "This works",
    Source = "http://daniel.wertheim.se",
    Type = TifiTypes.Blog
};

//Daniel

Caught my eye #1 – Parallel programming

Simple and concise getting started with parallel programming – guide.

Parallel Programming in .NET Framework 4: Getting Started – Alexandra Rusina