Wednesday, December 14, 2011

Stubbing out NHibernate's ISession

When I first started using NHibernate I didn't know much about design patterns. My early attempts were messy, ugly, and unstable. I finally learned about the repository pattern and started using it. Things were great, I was able to write cleaner code and was able to abstract away my use of NHiberante. The thing is, NHibernate's ISession is already an implementation of this pattern, in my opinion. So abstracting an abstraction just adds an extra layer of complexity. That's not to say that you shouldn't use the repository pattern to persist objects, but for basic reads, using the ISession directly, has a lot of benefits. (For a more thorough analysis see Ayende's blog here and here.)

There is, however, one advantage to abstracting away the ISession. It allows you to unit test your code in a much easier fashion. Since you can easily mock out your repository object, you can write unit tests for modules that use it. This is much easier than if you used the ISession directly. Whether you use the Criteria, QueryOver, or the Linq Query apis, it's almost impossible to stub out this interaction. If you do happen to stub it out using a mocking framework, your unit test Arrange step would become so messy, that your unit tests would become completely unreadable.

So what's the solution? In a recent project, we decided not to abstract away, NHibernate when doing queries. Of course, we ran up against the problem of unit testing the code. The solution was remarkable simple. Since we were using the QueryOver api, all we did was write a QueryOverStub implementation of the IQueryOver<TRoot, TSub>interface. Here's a simple implementation with unused methods not being implemented.


    public class QueryOverStub<TRoot, TSub> : IQueryOver<TRoot, TSub>
    {
        private readonly TRoot _singleOrDefault;
        private readonly IList<TRoot> _list;
        private readonly ICriteria _root = MockRepository.GenerateStub<ICriteria>();

        public QueryOverStub(IList<TRoot> list)
        {
            _list = list;
        }

        public QueryOverStub(TRoot singleOrDefault)
        {
            _singleOrDefault = singleOrDefault;
        }

        public ICriteria UnderlyingCriteria
        {
            get { return _root; }
        }

        public ICriteria RootCriteria
        {
            get { return _root; }
        }

        public IList<TRoot> List()
        {
            return _list;
        }

        public IList<U> List<U>()
        {
            throw new NotImplementedException();
        }

        public IQueryOver<TRoot, TRoot> ToRowCountQuery()
        {
            throw new NotImplementedException();
        }

        public IQueryOver<TRoot, TRoot> ToRowCountInt64Query()
        {
            throw new NotImplementedException();
        }

        public int RowCount()
        {
            return _list.Count;
        }

        public long RowCountInt64()
        {
            throw new NotImplementedException();
        }

        public TRoot SingleOrDefault()
        {
            return _singleOrDefault;
        }

        public U SingleOrDefault<U>()
        {
            throw new NotImplementedException();
        }

        public IEnumerable<TRoot> Future()
        {
            return _list;
        }

        public IEnumerable<U> Future<U>()
        {
            throw new NotImplementedException();
        }

        public IFutureValue<TRoot> FutureValue()
        {
            throw new NotImplementedException();
        }

        public IFutureValue<U> FutureValue<U>()
        {
            throw new NotImplementedException();
        }

        public IQueryOver<TRoot, TRoot> Clone()
        {
            throw new NotImplementedException();
        }

        public IQueryOver<TRoot> ClearOrders()
        {
            return this;
        }

        public IQueryOver<TRoot> Skip(int firstResult)
        {
            return this;
        }

        public IQueryOver<TRoot> Take(int maxResults)
        {
            return this;
        }

        public IQueryOver<TRoot> Cacheable()
        {
            return this;
        }

        public IQueryOver<TRoot> CacheMode(CacheMode cacheMode)
        {
            return this;
        }

        public IQueryOver<TRoot> CacheRegion(string cacheRegion)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> And(Expression<Func<TSub, bool>> expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> And(Expression<Func<bool>> expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> And(ICriterion expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> AndNot(Expression<Func<TSub, bool>> expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> AndNot(Expression<Func<bool>> expression)
        {
            return this;
        }

        public IQueryOverRestrictionBuilder<TRoot, TSub> AndRestrictionOn(Expression<Func<TSub, object>> expression)
        {
            throw new NotImplementedException();
        }

        public IQueryOverRestrictionBuilder<TRoot, TSub> AndRestrictionOn(Expression<Func<object>> expression)
        {
            throw new NotImplementedException();
        }

        public IQueryOver<TRoot, TSub> Where(Expression<Func<TSub, bool>> expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> Where(Expression<Func<bool>> expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> Where(ICriterion expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> WhereNot(Expression<Func<TSub, bool>> expression)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> WhereNot(Expression<Func<bool>> expression)
        {
            return this;
        }

        public IQueryOverRestrictionBuilder<TRoot, TSub> WhereRestrictionOn(Expression<Func<TSub, object>> expression)
        {
            return new IQueryOverRestrictionBuilder<TRoot, TSub>(this, "prop");
        }

        public IQueryOverRestrictionBuilder<TRoot, TSub> WhereRestrictionOn(Expression<Func<object>> expression)
        {
            return new IQueryOverRestrictionBuilder<TRoot, TSub>(this, "prop");
        }

        public IQueryOver<TRoot, TSub> Select(params Expression<Func<TRoot, object>>[] projections)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> Select(params IProjection[] projections)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> SelectList(Func<QueryOverProjectionBuilder<TRoot>, QueryOverProjectionBuilder<TRoot>> list)
        {
            return this;
        }

        public IQueryOverOrderBuilder<TRoot, TSub> OrderBy(Expression<Func<TSub, object>> path)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, path);
        }

        public IQueryOverOrderBuilder<TRoot, TSub> OrderBy(Expression<Func<object>> path)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, path, false);
        }

        public IQueryOverOrderBuilder<TRoot, TSub> OrderBy(IProjection projection)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, projection);
        }

        public IQueryOverOrderBuilder<TRoot, TSub> OrderByAlias(Expression<Func<object>> path)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, path, true);
        }

        public IQueryOverOrderBuilder<TRoot, TSub> ThenBy(Expression<Func<TSub, object>> path)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, path);
        }

        public IQueryOverOrderBuilder<TRoot, TSub> ThenBy(Expression<Func<object>> path)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, path, false);
        }

        public IQueryOverOrderBuilder<TRoot, TSub> ThenBy(IProjection projection)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, projection);
        }

        public IQueryOverOrderBuilder<TRoot, TSub> ThenByAlias(Expression<Func<object>> path)
        {
            return new IQueryOverOrderBuilder<TRoot, TSub>(this, path, true);
        }

        public IQueryOver<TRoot, TSub> TransformUsing(IResultTransformer resultTransformer)
        {
            return this;
        }

        public IQueryOverFetchBuilder<TRoot, TSub> Fetch(Expression<Func<TRoot, object>> path)
        {
            return new IQueryOverFetchBuilder<TRoot, TSub>(this, path);
        }

        public IQueryOverLockBuilder<TRoot, TSub> Lock()
        {
            throw new NotImplementedException();
        }

        public IQueryOverLockBuilder<TRoot, TSub> Lock(Expression<Func<object>> alias)
        {
            throw new NotImplementedException();
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, U>> path)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<U>> path)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, U>> path, Expression<Func<U>> alias)
        {
            return new QueryOverStub<TRoot, U>(_list);
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, U>> path, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<U>> path, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, U>> path, Expression<Func<U>> alias, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, IEnumerable<U>>> path)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, IEnumerable<U>>> path, Expression<Func<U>> alias)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, IEnumerable<U>>> path, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<TSub, IEnumerable<U>>> path, Expression<Func<U>> alias, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias, JoinType joinType)
        {
            return new QueryOverStub<TRoot, U>(new List<TRoot>());
        }

        public IQueryOver<TRoot, TSub> JoinAlias(Expression<Func<TSub, object>> path, Expression<Func<object>> alias)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> JoinAlias(Expression<Func<TSub, object>> path, Expression<Func<object>> alias, JoinType joinType)
        {
            return this;
        }

        public IQueryOver<TRoot, TSub> JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias, JoinType joinType)
        {
            return this;
        }

        public IQueryOverSubqueryBuilder<TRoot, TSub> WithSubquery
        {
            get { return new IQueryOverSubqueryBuilder<TRoot, TSub>(this); }
        }

        public IQueryOverJoinBuilder<TRoot, TSub> Inner
        {
            get { return new IQueryOverJoinBuilder<TRoot, TSub>(this, JoinType.InnerJoin); }
        }

        public IQueryOverJoinBuilder<TRoot, TSub> Left
        {
            get { return new IQueryOverJoinBuilder<TRoot, TSub>(this, JoinType.LeftOuterJoin); }
        }

        public IQueryOverJoinBuilder<TRoot, TSub> Right
        {
            get { return new IQueryOverJoinBuilder<TRoot, TSub>(this, JoinType.RightOuterJoin); }
        }

        public IQueryOverJoinBuilder<TRoot, TSub> Full
        {
            get { return new IQueryOverJoinBuilder<TRoot, TSub>(this, JoinType.FullJoin); }
        }
    }

So you can easily specify the item or list of items you want the query to return in your test.

new QueryOverStub<Entity, Entity>(new List<Entity>())

The only thing missing is: if you're using projections or getting something like the count. In order to make this implementation work in those situations, we would just need to write implementations for the List<U> and SingleOrDefault<U> methods. In an upcoming blog post I'll talk about how to use an in memory Sqlite database as an alternative to using this stub.

Monday, November 28, 2011

Writing testable ETL processes with Rhino-ETL

On a recent project we had to integrate several external data sources into the application database. Some of these sources were csv files, while another one was an Oracle database. Our application, meanwhile, used a SQL Server database. Furthermore some of the data had to be loaded automatically, while other data had to be loaded by a business user. We tossed around several ideas for how to accomplish this: SSIS, Informatica, something custom built. We finally arrived on Ayende Rahien's (aka Oren Eini) ETL framework Rhino-ETL. It looked like it would fit the bill as it could be integrated into any .NET application and it allowed us to write unit and integration tests around it.

Unfortunately there is a dearth of information around how to use this framework. The only good piece of documentation is this great video tutorial. While a good starting point, I thought I'd write a blog to show how to get started with the framework.

Rhino ETL is based on a pipeline concept. Each process consists of a bunch of operations strung together. Each operation's output is fed into the next operation as input. The operations interact by the following method:

public interface IOperation : IDisposable
{
    ...
    IEnumerable<Row> Execute(IEnumerable<Row> rows);
    ...
}

So each operation takes in a collection of Rows and outputs a collection of Rows. A Row is basically an instance of Dictionary<object, object> with an added twist: no exceptions are thrown if a key does not exist. A Row will simply return null when a key does not exist in the dictionary. Each operation can also leverage the oft unused C# keyword of yield return. A typical operation might looks something like this:

public class MyOperation : AbstractOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
    {
        foreach (var row in rows)
        {
            //process the row
            yield return row;
        }
    }
}

The yield return keyword instructs the compiler to generate an iterator that, for each row, would execute whatever code you had in the foreach statement. This allows us to defer execution of each row to the point in time when it passes through the operation pipeline.

Since your operations expose the Execute method, you can easily write unit tests around each operation, with any kind of data as input. Voila, by using this framework and developing a good suite of unit tests, your ETL process has become far more robust than if you were using a tool like SSIS.

The main thing to note about Rhino-ETL is that you will have to code all of your operations. Typically your operations will inherit from the AbstractOperation class. Some other useful operations:
SqlBulkInsertOperation
Set up the schema and do a bulk insert into a table. Useful for inserting large data sets quickly and efficiently
SqlBatchOperation
Batch your sql operations to reduce server roundtrips
BranchingOperation
Send rows to multiple operation pipelines
JoinOperation
Join your rows to a result set from another operation
PartialProcessOperation
Typically used with BranchingOperations to create an operation pipeline within a branch

A process is typically created by inheriting from the EtlProcess class.

public class MyProcess : EtlProcess
{
    protected override Initialize()
    {
        Register(new MyOperation());
        //register other operations
    }
}

A final note, in order to get any output from your etl process you will need to set log4net up. A simple console output can be created by the following entry in your App.config:

<log4net debug="false">
    <appender name="console" type="log4net.Appender.ConsoleAppender, log4net">
      <threshold value="WARN" />
      <layout type="log4net.Layout.PatternLayout,log4net">
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
      </layout>
    </appender>
    <root>
      <level value="INFO" />
      <appender-ref ref="console"/>
    </root>
  </log4net>

and by adding the following line of code to your application startup:

log4net.Config.XmlConfigurator.Configure();

To conclude, while you do give up fancy designers and useful operations like SSIS's Fuzzy Lookup, the benefit gained from being able to write unit tests around your ETL process can be invaluable. Due to its simplicity and the fact that it can be easily integrated into other .NET applications, Rhino ETL is a very useful tool to have in your arsenal.

Wednesday, July 13, 2011

Why you should use a DVCS

Over the last several years DVCSs (Distributed Version Control Systems) have gained enormous acceptance in the development community. There are a lots of good reasons to ditch your old Subversion (or god forbid CVS) repository and switch to one of the new kids on the block like Git or Mercurial. Let's take a look at some of these reasons.

Experiment to your heart's content

I'm sure this has happened to everybody. You start developing a feature. You change a few minor things here and there (e.g. add a new property or method to an entity). Then you make a few more changes; and a few more; and a few more. All of a sudden you realize that your approach just isn't going to work. Hold on though, some of the changes you made earlier are still valid and you want to keep them. So you start trying to revert just the later changes, only to give up and revert everything back to the latest copy that was in source control. Begrudgingly you reproduce your earlier work as you curse your source control system.

If you're using a DVCS, all of that can be avoided. Since you have a source control repository right on your own machine, tracking your code. You can easily reset your code to one of the commit points along your journey to the dead end you've found yourself in. You can even save your progress in a tag or a branch, in case you want to refer to some of the code in the future.

Branch and merge with ease

A common scenario in software development is to do a product release, create a release branch, and continue development on the main line trunk. If a bug is reported in the release, you would check out the release branch, fix the bug and check in your changes. After a few of these changes you can do another release and merge your branch fixes into your main line trunk. At least that's how it's supposed to work. What happens more often is on the last step, when you try to do a merge, you find so many conflicts that it then takes the entire team a day or more to resolve them.

Since a DVCS is built around branching and merging, these operations are not only easy to do, but also painless. Most of the time you won't even need to manually merge anything as the systems are very good at figuring out what was intended. So go ahead, make as many branches as you want, merge them whenever you want, and stop trying to mangle your process with the limitations of your VCS.

Safety and redundancy

One of the great things about having multiple copies of the repository floating around among the development team and the central location is redundancy. In a traditional central version control system environment, if your your repository became corrupted, or the server hard drive failed, you would have to go find a backup and restore it, possibly losing work and holding up development.

In a distributed environment, everyone has a copy of the repository. So if the same scenario were to happen, the fix can be as simple as one of the developers pushing in the latest copy to a new shared location. Alternatively one developer's repositories can be chosen to be a central repository until the server can be rebuilt. That is not to say you shouldn't have backups in a distributed environment, but it is far less catastrophic not to have them.

The bottom line is that constantly working with the benefits of source control far outweigh the initial pain of converting to a DVCS. If you're developing in Windows, I highly recommend Mercurial, if Linux or Mac is your preferred environment, then Git is definitely the way to go. So go on and give it a try. I promise you won't go back to your old VCS.

Monday, May 30, 2011

Git with ssh on Windows

While Git is a great source control system that can bend to almost any source control workflow you might have, support on windows varies from awesome (Git Extensions, msysgit) to downright awful (using git, ssh, or http protocol). I've struggled enough with setting up an ssh server on windows to host a central repository to warrant documenting it.

First you will need to install Cygwin with the openssh and git modules enabled.

After the installation we'll need to let cygwin know about the domain accounts we want to use. For this we'll use the mkpasswd command. For domain accounts use the '-d' option.

$ mkpasswd -d -u username >> /etc/passwd

This will append the entry to the /etc/passwd file. Do this for all of the accounts you want to add. You may need to subsequently edit the /etc/passwd file and set the appropriate home directory to /home/username especially if your company likes to have a network home drive for all of their users.

Now it's time to create a new bare repository.

$ git init --bare myrepo.git
$ git config core.sharedRepository group

The second command lets git know that it should use group write permissions when creating files and directories. We'll also want to set the group permissions to special so that newly created files and folders have the same group permissions.

$ chmod -R g+ws .

Now that your repository is set up. Let's setup the ssh server.

$ ssh-host-config

The script will begin by generating host key files and config files. It will then prompt you to use privilege separation. Answer yes and again when it prompts you to create an unprivileged user.

Next the script will ask if you want to install sshd as a service. Answer yes. The next question will tell you that you need a privileged account to run the service and if you want to use the name 'cyg_server'. Either say no, or if you already have an appropriate privileged account answer yes and enter the name you want to use. If the account you entered does not have the appropriate permissions the script will warn you. I recommend letting the script create a 'cyg_server' account. When prompted enter an appropriate password that conforms to your password policies.

Finally the script will ask you to enter the values for the CYGWIN environment variable. Enter 'tty acl'. This will let you use windows security to access the file system and insert appropriate characters.

After all of that, ssh will be configured so we just need to start it.

$ cygrunsrv --start sshd

Alternatively you can go into the services list, find CYGWIN sshd and start it there.
If you start seeing errors at this point there is likely something wrong with the password you set up for the 'cyg_server' account.

As a final step you will likely want to create a symlink to your repository in the root folder. This will allow the ssh URI to be more concise and friendly.

$ ln -s /path/to/your/repo /repo

Once you have the ssh server running, it's time to connect to it. Let's push our local repository to the remote.

$ git push ssh://server/repo

If you did not set up a symlink your address will need to contain the appropriate cygwin path to your repo starting from /. The first time you connect it will prompt you to add the host key to your known_hosts file. Finally you will be prompted you to enter your password. At this point you have everything in place to access the repository remotely.

As a final step you can set up public/private keys in order to identify yourself to the ssh server. This will allow you to forgo having to enter your password. First, set up your ssh keys

$ ssh-keygen -t rsa

This will create 2 files in your ~/.ssh drive, one is your public key (id_rsa.pub) and the other is your private key (id_rsa). The process will involve you copying the contents of your public key to a /home/username/.ssh/authorized_keys file on the server. One way of doing this is to create a share to your home drive on the server that only your account can access, then you can create an authorized_keys file and copy the contents in notepad.

Git can still be a pain to work with on Windows, but hopefully this will make your life a little easier.

Update:
If you would rather set up git via http protocol. Have a look at this post if you want to go via Apache. Or for an IIS solution check this out.

Wednesday, May 4, 2011

Custom properties for IPrincipal

Sometimes you need to provide application specific values that are associated with a particular user. Let's say your application must handle role based security by using AD groups. Furthermore let's say that you wanted those group mappings to be configurable. A way to solve this would be to create your own implementation of IPrincipal. It might look something like this:

public class ApplicationPrincipal : IPrincipal
{
    private readonly IIdentity _identity;
    private readonly IPrincipal _principal;
    private readonly ISecurityConfiguration _config;

    public class ApplicationPrincipal(IIdentity identity, IPrincipal principal, ISecurityConfiguration config)
    {
        _identity = identity;
        _principal = principal;
        _config = config;
    }

    public IIdentity Identity { get { return _identity; } }

    public bool IsInRole(string role)
    {
        var windowsGroup = MapInternalRoleToWindowsGroup(role);
        return _principla.IsInRole(windowsGroup);
    }

    public string MapInternalRoleToWindowsGroup(string role)
    {
        switch (role)
        {
            case "Admin": return _config.AdminGroup;
            case "User": return _config.UserGroup;
            default: throw new SecurityException("Invalid group name: " + role);
        }
    }
}

Now that we have our own principal implementation we need a way to let the application access it. A good place to do that would be in an HttpModule that handles the PostAuthenticateRequest event.

public class ApplicationPrincipalModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostAuthenticateRequest += PostAuthenticateRequest;
    }

    public void Dispose()
    {
        context.PostAuthenticateRequest -= PostAuthenticateRequest;
    }

    private void PostAuthenticateRequest(object sender, EventArgs e)
    {
        var httpContext = HttpContext.Current;
        var principal = new ApplicationPrincipal(
                             httpContext.User.Identity, httpContext.User, 
                             new SecurityConfiguration());
        httpContext.User = principal;
    }
}

Once a user has been authenticated, by whichever method your application is set up to authenticate, this module will set the HttpContext.Current.User to your implementation of IPrincipal. This can then be referenced where needed in your application.

Monday, April 4, 2011

Getting started with BDD using NBehave

What is BDD? BDD stands for Behavior Driven Development and at its core is about implementing an application by describing its behavior from the perspective of its stakeholders. It is an agile software development methodology that started as an offshoot of TDD. However, in my opinion it is better suited to software delivery than TDD is. The reason is that TDD is great as a code design methodology, but there is a disconnect between code design and stakeholder value. When practicing TDD, developers typically produce cleaner and more maintainable code. However, that elegant code may not deliver what the stakeholders wanted.

BDD also allows non technical users, like BAs and business users to specify system behavior in a non technical, natural language. Tools like NBehave, allow the developers to verify and demonstrate that the system delivers what the stakeholders expect.

How do we write a scenario? Scenarios typically follow the Given/When/Then structure. So for example:

Scenario: User logs in
Given that I am not logged in
And I have an account
When I enter my username and password
Then I should see “Welcome Vadim”

How would we use NBehave to verify that the system does what the scenario says? First thing's first download the latest NBehave build and extract the contents of the zip file.
There are 2 versions of the DLLs, one for .Net 3.5 and one for .Net 4.0.

Create a project for your tests and add a reference to NBehave.Narrator.Framework.dll. Also add a reference to your favorite testing framework (like NUnit or xUnit) and the appropriate NBehave.Spec.<framework>.dll. Currently NBehave comes with extension methods for NUnit, xUnit, MbUnit, and MSTest. These methods are simply wrappers around Assert statements, that allow a more natural language feel when writing your code. So if you're using something like MSpec, which already has Should<DoSomething> type assertions, then you don't need to worry about this last step.

Next, create a features directory inside your project. This is where you'll store your feature and scenario files. Let's pretend we're writing a calculator application. Add a file to the features folder called calculator_turns_on.feature. Time to write our scenario.

Scenario: I turn on the calculator
Given the calculator is off
When I press the on button
Then the calculator should display 0

Let's add a folder called steps. This is where we're going to put our tests. Also create a code file and call it CalculatorTurnsOn.cs. Let's start with a skeleton test:

[ActionSteps]
public class CalculatorTurnsOn
{
    
}

Compile the solution then run the NBehave-Console like so

NBehave-Console.exe bin\Debug\NBehaveIntro.dll /sf=features\calculator_turns_on.feature

You should see all results yellow with a PENDING tag next to them. These aren't failures, but we know that we have to implement this scenario. Let's create a Calculator class.

public class Calculator
{
    public float Display { get; set; }
}

Next we'll flesh out our test.

[ActionSteps]
public class CalculatorTurnsOn
{
    private Calculator calculator;

    [Given("the calculator is off")]
    public void CalculatorOff()
    {
        calculator = null;
    }

    [When("I press the on button")]
    public void TurnCalculatorOn()
    {
        calculator = new Calculator();
    }

    [Then("the calculator should display 0")]
    public void CalculatorDisplayIs0()
    {
        calculator.Display.ShouldEqual(0);
    }
}

Compile and run the command again. Now the tests all pass.

Note how the attributes are decorated with the same sentences that were written in our scenario. That's how NBehave knows how the scenarios are mapped. You can decorate a method with multiple Given, When, and Then attributes and you can have any number of methods in a given ActionSteps class. Furthermore, you can have regular expressions or string tokens in the description as well. For example if we had the following scenario:

Scenario: I can add two numbers
Given numbers [one] and [two]
When I add them
Then the sum should be [sum]

Examples:
|one|two|sum|
|1  |2  |3  |
|2  |2  |4  |
|10 |35 |45 |

Our attribute decorations might look like:
[Given("numbers $one and $two")]
public void TwoNumbers(float one, float two)
...
[Then("the sum should be $sum")]
public void VerifySum(float sum)
...

One last note, the scenario above also contained an example table. This table allows us to write one scenario with multiple inputs and outputs to test. This saves us from having to write repetitive scenarios when warranted.

For further info see the following links:
http://nbehave.org/
http://nbehave.codeplex.com/wikipage?title=0.5.0&referringTitle=Documentation

Monday, March 21, 2011

NHibernate unit of work in MVC using Ninject (part 2)

In part 1 I talked about a problematic NHibernate Unit of Work implementation that we had in our MVC application. In part 2 I will talk about why this approach turned out to be problematic and the ultimate solution that we came up with.

If you recall, the original solution was to use an HttpModule to subscribe to the BeginRequest and EndRequest events. When we upgraded to Ninject 2.1, none of our entities would get saved. Reads all worked fine, but no CUD actions worked. The problem turned out to be due to a new component of Ninject called the OnePerRequestModule. This module subscribes to the EndRequest event and disposes any objects that were bound in request scope. The problem was that this module would dispose of our session, before we had a chance to commit the transaction and end the session ourselves. It was also registering first (which meant it was first to handle EndRequest) and there appeared to be no hook to turn it off.

The solution that we came up with was to use a filter attribute in order to encapsulate our unit of work. The first part of the refactor was to create an IUnitOfWork interface:

public interface IUnitOfWork
{
 void Begin();
 void End();
}

That's all a unit of work really should look like. Second we moved our BeginSession and EndSession code into an implementation of IUnitOfWork:

public class NHibernateUnitOfWork : IUnitOfWork, IDisposable
{
 private readonly ISession _session;

 public NHibernateUnitOfWork(ISession session)
 {
  _session = session;
 }

 public void Begin()
 {
  _session.BeginTransaction();
 }

 public void End()
 {
  if (_session.IsOpen)
  {
   CommitTransaction();
   _session.Close();
  }
  _session.Dispose();
 }

 private void CommitTransaction()
 {
  if (_session.Transaction != null && _session.Transaction.IsActive)
  {
   try
   {
    _session.Transaction.Commit();
   }
   catch (Exception)
   {
    _session.Transaction.Rollback();
    throw;
   }
  }
 }

 public void Dispose()
 {
  End();
 }
}

This separated repository logic from the unit of work implementation. The binding for this implementation was bound in request scope. Finally we created our filter attribute:

public class UnitOfWorkAttribute : FilterAttribute, IActionFilter
{
 [Inject]
 public IUnitOfWork UnitOfWork { get; set; }

 public UnitOfWorkAttribute()
 {
  Order = 0;
 }

 public void OnActionExecuting(ActionExecutingContext filterContext)
 {
  UnitOfWork.Begin();
 }

 public void OnActionExecuted(ActionExecutedContext filterContext)
 {
  UnitOfWork.End();
 }
}

The order was set to 0 to ensure that this filter was always run first. We also did not have to explicitly call End on the unit of work since it would be disposed at the end of the request and would call End itself. However, it's good practice to be explicit with these things. Finally you can apply this filter at the controller level or the action level. So you can decorate only those actions that actually perform data access.
8USTXZWHRBTH