Sergey Shishkin

on agile software development

Archive for August 2008

Week Of Great Tools

This week should be officially called "The week of great tools." First, StyleCop 4.3 came out with new brand, new features and less bugs. Then, the new 3.6 release of FxCop. And the latest news: Red Gate takes over the .NET Reflector. The week is not over, though. Anything else? 😉

Technorati Tags: ,,
Advertisements

Written by Sergey Shishkin

22.08.2008 at 02:22

Posted in Tools

Unit Of Work Pattern Revised

The last post in my data access trilogy (see also repository and specification) is about the Unit of Work pattern.

When working with NHibernate you have a unit of work for free as its ISession interface. Moreover, one have to use ISession in some way in order to get something useful out of NHibernate. However, using it directly in the application layer is very dangerous. The application gets coupled to NHibernate forever. It’s nothing even close to the Onion Architecture.

Another approach would be to introduce yet another layer of abstraction. This general approach can solve any problem except the problem of too many layers of abstraction. There should be a simpler way to manage connections, transactions and units of work, and all that not coupled to NHibernate!

Back To The Beginning

Let’s assume for a moment that we couple the application to NHibernate. Then what we might do in an application layer service method is something like this:


using
(var session = SessionFactory.OpenSession())

using (var tx = session.BeginTransaction())

{

    //…

 

    session.Flush();

    tx.Commit();

}

Now in that using scope we have a session instance that we use to instantiate repositories and do all the work. Repositories don’t have to manage neither connections, nor transactions, nor units of work. They just write to the provided session.

Transactions Are Units Of Work

An important fact to notice about the code snippet above is that it runs the unit of work in a transaction. So why then we have to code against two separate abstractions (NHibernate’s ISession and ITransaction) when they both mean the same concept (unit of work) to the application?

A much better way would be to use only one abstraction instead and let it manage the others under the hood. But wait starting to code the IUnitOfWork interface. There is a yet simpler solution.

Plain old .NET ambient transactions (which I assume every .NET developer is already familiar with) can represent units of work for the application layer:


using
(var tx = new TransactionScope())

{

    //…

 

    tx.Complete();

}

The application layer then has no dependencies whatsoever to NHibernate. As a bonus we get a transaction across any resources that support ambient transactions (MSMQ, for example) (although transactions over multiple resources come with the price of Distributed Transactional Coordinator).

It is now responsibility of the repository implementation to obtain an appropriate session (get current or open new) whenever the repository is called. The transaction’s completed event can be used to flush the session if the transaction has been committed and close it to free the connection.

Logging And Auditing

But wait, what about logging? How can I log an error to a transactional store, if it automatically gets rolled back? To suppress the current ambient transaction in special cases (like logging) the TransactionScope supports options:


using
(var noTx = new TransactionScope(TransactionScopeOption.Suppress))

{

    log.Write(exception);

 

    noTx.Complete();

}

Isolation Level

There is also an overload to specify the isolation level of the transaction, when tuning performance of concurrent requests:


using
(var tx = new TransactionScope(

    TransactionScopeOption.Required,

    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))

{

    // read-only operation here

 

    tx.Complete();

}

Summary

In this post I described how one can reuse the common .NET abstraction of ambient transactions as a unit of work and thus hide the infrastructure away from application developers and avoid introducing new abstractions into the application. In this approach coupling is inverted relative to the first code sample. Now the session (NHibernate-specific unit of work) is coupled to the .NET ambient transaction (application unit of work), and not the other way around. Still one can implement advanced connection management under the hood to support batching of multiple transactions (units of work) in a single database connection.

Series Summary

In the last three posts (see also repository and specification) I described how one can implement data access infrastructure while keeping the rest of the application independent of it. I use NHibernate as the O/R Mapper of choice, though the principles described here are applicable to almost any .NET data access technology. Once again, the principles are:

  • Use the repository pattern to abstract the data access infrastructure;
  • Use Linq and the specification pattern to abstract queries;
  • Use .NET ambient transactions as units of work.

When sticking to these principles, the specific data access infrastructure (be it NHibernate or anything) can be hidden away from application developers and hence lower the learning curve in a project. Of course, somebody still has to deal with actual mappings, but it can be the DBA! 😉

 

Written by Sergey Shishkin

17.08.2008 at 20:25

Posted in Data Access

Specification Pattern Revised

(see also repository and unit of work)

Unfortunately, current implementation of Linq2NH does not support queries like this:


from
customer in repository.AllEntities()

where specification.IsSatisfiedBy(customer)

select customer

The cause is that Linq2NH can’t translate the call to the specification’s method into the appropriate call to the Criteria API. What can be done instead is encapsulation of queries into C# extension methods. We can do this in two ways:

Chaining IQueryable<T>

First one is chaining of IQueryable<T> methods like this:


public
static IQueryable<Customer> FindByName(this IQueryable<Customer> customers, string query)

{

    return

        from customer in customers

        where customer.FirstName.StartsWith(query) ||

            customer.LastName.StartsWith(query)

        select customer;

}


from
customer in repository.AllEntities().FindByName(name)

select customer;

Extending IRepository<T>

Alternatively, you can write extension methods for IRepository<Customer> like this:


public
static Collection<Customer> FindByName(this IRepository<Customer> repository, string query)

{

    var linq =

        from customer in repository.AllEntities()

        where customer.FirstName.StartsWith(query) ||

            customer.LastName.StartsWith(query)

        select customer;

    return new Collection<Customer>(linq.ToList());

}


var
customers = customerRepository.FindByName(name);

These two approaches are not a mutual exclusion. You can apply them together for better results. Encapsulate simple queries into IQueryable<T> extension methods. Then combine them to implement more complex IRepository<T> extension methods, available to the application layer.

 

Written by Sergey Shishkin

17.08.2008 at 16:32

Posted in Data Access

Repository Pattern Revised

(see also specification, unit of work)

It Should Not Be That Complex

Last week I was implementing NHibernate-based data access infrastructure. While looking for existing implementations I saw a lot of code, where NHibernate leaks into the domain layer either in the form of queries (HQL or Criteria API) or a Unit of Work. Although some of the implementations succeed in decoupling the infrastructure and the domain layers, still these implementations are much too complex to maintain. For example, if you abstract complex queries with Specifications, you still have specification implementations coupled to NHibernate. Also manipulating pure ISession objects in the application layer is commonly considered to be OK.

This post series provides a much simpler look at the implementation of the good old repository (this post), specification and unit of work patterns.

Linq To Rescue

Though we have some issues with Linq to SQL, the Linq itself allows us to get rid of HQL and Criteria in our domain layer. Thanks to Linq to NHibernate (Linq2NH) we can now abstract NHibernate queries with the nice Linq syntax. Meet the simplest ever repository interface:

public interface IRepository<T>

{

    void Save(T entity);

    void Delete(T entity);

    T Get(object key);

    IQueryable<T> AllEntities();

}

Now we can write client code like this:

var customers =

    from customer in repository.AllEntities()

    where customer.FirstName.StartsWith(name) ||

        customer.LastName.StartsWith(name)

    select customer;

Queries are now expressed in Linq and are not coupled to the infrastructure. Great! But now queries are all around. Let’s encapsulate them.

 

Written by Sergey Shishkin

17.08.2008 at 16:32

Posted in Data Access

Applying The Message Bus

In the last post I was pursuing Remoteness Ignorance using the Message Bus pattern. I would like to emphasize that I tend to use messaging not only for remote communication (e.g. client-server) but also for in-process communication between different modules of the application (or bounded contexts in terms of DDD). Message Bus encapsulates the communication infrastructure while the domain layer works with messages and the Message Bus interface-based API.

Message Bus API

How could this API look like? Well, starting with very simple cases, one could send a message somewhat like this:

bus.Send(new PatientSearchRequest("bob"));

Subscription Manager

In order to receive and handle this message first we need a subscriber:

public class PatientSearchHandler : ISubscriber<PatientSearchRequest>

{

    public void Handle(PatientSearchRequest message) { … }

}

When we have the subscriber in place, we might want to register it by the bus. To avoid unnecessary object instantiation the bus should support different subscription options: with an instance and with a type. Moreover, we might want to automatically subscribe all the ISubscriber implementers from the IoC container. I implemented a Windsor facility for the purpose of auto-subscription which in turn calls the Subscription Manager on the bus:

bus.SubscriptionManager.Subscribe(subscriberType);

The Subscription Manager is an essential element of the Message Bus. It handles subscriptions and dispatches the received messages to appropriate subscribers, so that the bus can focus on sending and receiving messages.

Reply

Now it’s time to implement the subscriber’s Handle method. The implementation is very simple:

var patients = repository.FindByName(message.Query);

message.Reply(new PatientSearchResponse(patients));

The subscriber does not even have to know the bus, the Message base class takes care of it.

The request has been sent, and the subscriber has responded. But how does the sender actually gets the response? The sender, of course, could implement the ISubscriber interface in order to handle the reply, but we want to allow multiple senders to send different requests and to receive their (and only their) replies.

We obviously need to correlate requests and replies. The Message base class’ Reply method does exactly that. Messages are correlated per CorrelationId, so that the bus can dispatch the reply to the right sender. But wait, the bus does not know the sender!

Callbacks

Here is where Callbacks come into play. The sender registers a Callback which will be called upon the dispatch of the response message:

bus.Send(new PatientSearchRequest("bob"))

    .OnResponse<PatientSearchResponse>(
        response => AppendResults(response.Patients))

    .OnTimeout(() => ResultsComplete())

    .WithTimeoutInterval(TimeSpan.FromSeconds(5))

    .WaitForMultipleResponses;

Actually, this is more than just a simple callback delegate. It is a fluent API for configuring a Callback object, which is registered by the bus for dispatching responses. The Callback object takes care of timeout timers. It also takes care of thread context synchronization, because the incoming messages are processed in worker threads, while the sender sometimes wants to touch the GUI upon the callback.

Another important thing about Callbacks is that we allow multiple responses to be received (see the WaitForMultipleResponses property). It means that the delegate specified in the OnResponse method will be called potentially many times. In this case importance of Timeouts emerges drastically. Upon timeout no further correlated responses are dispatched to the sender. The sender has an opportunity to be notified of the timeout with a delegate passed to the OnTimeout method.

This is a relatively complex scenario. The sender is awaiting for search results from multiple services. Maybe a caching layer in the bus has intercepted the request and sent the reply from the cache. Maybe the patient registry is distributed and each node answers with an individual response. In either case the sender is remains unaware of these infrastructure aspects.

A simplified version of the sample above only waits for single response and uses the default timeout interval:

bus.Send(new PatientSearchRequest("bob"))

    .OnResponse<PatientSearchResponse>(

        response => ShowResults(response.Patients));

In this case the Callback object will be dismissed right after dispatching the first response message, or upon timeout, if no response has been received.

Summary

We just saw a simple API of the Message Bus sending and dispatching messages. The Message Bus relies on the Subscription Manager and Callback objects for dispatching messages. The Message base class takes care of message correlation for replies.

In further posts I’ll show some implementation details of the API described above. Stay tuned 🙂

Technorati Tags: ,

Written by Sergey Shishkin

11.08.2008 at 01:22

Posted in Uncategorized

Remoteness Ignorance

Term

Let me coin this term for a software engineering principle of organizing communications between components in a way, independent of components’ locations (where are they deployed).

There are more general principles like Autonomy (hmm.. no wikipedia article for it?) or Loose Coupling, but I want to focus on the remoteness aspect explicitly.

Misleading Approach

Previously I always tried to hide communication infrastructure behind interfaces of my services. I thought it was Remoteness Ignorance. (The idea were the same as putting data-access code behind a repository interface to achieve Persistence Ignorance.)

It looks good for the first time: you call the same interface methods, no matter where actually the service, implementing the interface is sitting: same or another AppDomain, another process, another machine, another network. Quite remoteness-ignorant, nice.

Real World

Naïve illusions. They vanish when slow connections and partially connected clients come. Now I have to care about transport-related exceptions, timeouts and asynchronous programming model.

Problem

It means that I got my service interface polluted with those infrastructure concerns. Moreover, I have to implement the same infrastructure functionality for each service agent, even if it’s local. What I wanted was separating the domain and infrastructure concerns.

I identified the problem to be the well-known RPC communication style. RPC inherently mix domain with infrastructure.

Solution

As an alternative I tried to explore asynchronous messaging and the Message Bus pattern. In a messaging world the message represents domain knowledge while the message bus takes care of the infrastructure.

It gave me real Remoteness Ignorance because implementation details of the infrastructure (transports, queues, protocols) are well hidden behind the message bus interface (just as a repository hides data access logic).

Moreover, messaging brings other benefits valuable for Autonomy:

  • Services are only coupled to message contracts, not to each other.
  • Communications are also distributed in time now (asynchronous).
  • Services are more robust, since they make no assumptions regarding presence of their counterparts.

I plan to discuss asynchronous messaging and the Message Bus in upcoming posts here. The real implementation and some code samples will also come. So, stay tuned 😉

Written by Sergey Shishkin

01.08.2008 at 10:38

Posted in Uncategorized