Saturday
Oct312009

Monospace Open Space Thursday Schedule

There seemed to be some interest in the Monospace Open Space Friday Schedule that I published earlier this week.  No doubt, the majority of the interest was from people at the conference, but I thought others might be interested in what was discussed on Thursday as well.

1:00 – 2:15pm

Room 18B – MonoTouch Testability and Architecture – Brian Donahue

Room 18C – Starting an Open Source Project or Contributing to an existing one and the best way to go about it – Ryan Svihla

Room 18D – Moving to Mono: Why? How? – Michael Maham

2:15 – 3:30pm

Room 18B – Codeplex FoundationSam Ramji

Room 18C – Integrating open source into corporate software – Mike Sheldon

Room 18D – Distributing on Linux (deb, rpm, huh??) – Frank Bergmann

Thursday
Oct292009

Monospace Open Space Friday Schedule

I expect that this schedule will be available on the Monospace web site here at any time.  Until then, here it is:

9:00 – 10:15am

Room 18B - MonoDevelop vs Visual Studio + Resharper (what do we need to add) – Josh Flanagan

Room 18C – Silverlight and Windows Presentation Foundation (WPF) Best Practices – Justin Angel

Room 18D – 0 to 60 on Linux for Noobs

 

10:15 – 11:30am

Room 18B – Jazz Band Management (with Miguel de Icaza) – Kirstin Juhl

Room 18C – Build Your First Linode for Running ASP.NET – Eric Hexter

Room 18D – Adding Scripting To Your Applications (and making them cross-platform)

 

1:00 – 2:15pm

Room 18B – MonoTouch Pairing – Kirsten Juhl

Room 18C – Mono.AddIns, Managed Extensibility Framework (MEF), and/or Inversion of Control – Josh Flanagan

Room 18D – Using NHibernate in High Transaction Applications – Mike Sheldon

 

2:15 – 3:30pm

Room 18B – Lessons Learned by Reading Open Source Software (Architecture, etc.) – Frank Krueger

Room 18C – Legal Issues in Technology (Independent Contractors, Open Source Software, Intellectual Property (Copyright vs. Trademarks vs. Patents) – John Petersen

Room 18D – Automated Build with RakeScott Bellware

Wednesday
Oct142009

NHibernate Transactional Boundaries

In NHibernate Bootstrapping with StructureMap, I did not address the issue of transactional boundaries. The example had very simple controller actions that managed their own commits. However, this question on StackOverflow left me wondering who should be responsible for the commit?

Sharp Architecture’s Approach

Sharp Architecture is an excellent “architectural foundation for building maintainable web applications with ASP.NET MVC”. It has an Action Filter called Transaction that starts a transaction in the OnActionExecuting event, and then commits if no exception occurred. Otherwise, it explicitly rolls the transaction back. In fact, the Implicit transactions thread in the Sharp Architecture Google group discusses the Transaction attribute and some of the issues using it. The Transaction attribute provides the functionality that I want, but it requires the developer to decorate each Action method with an attribute. Why not make the HttpModule that creates and disposes of the Unit of Work handle the commit?

Modified Bootstrapping Example

I have modified the Bootstrapping NHibernate with StructureMap example from my previous post to do just that. Now, the NHibernateModule is responsible for calling Commit() on the UnitOfWork. Here is the NHibernateModule’s new Dispose method:

public void Dispose()
{
    _unitOfWork.Commit();
    _unitOfWork.Dispose();
}

The only addition is the call to the _unitOfWork.Commit(). However, now that the NHibernateModule is responsible for the commit, the developer can not abort an existing transaction. So, I added a Rollback() method to the IUnitOfWork class. The concrete implementation, UnitOfWork, calls _transaction.Rollback().

One final change to the UnitOfWork prevents it from throwing an exception if the developer explicitly calls commit by checking the ITransaction’s IsActive property before attempting to commit. Here is the UnitOfWork’s new Commit method:

public void Commit()
{
    if (_transaction.IsActive)
        _transaction.Commit();
}

Multi-Transaction Unit of Work

There is still one issue nagging at me. Once the developer commits the unit of work, the transaction is closed. The FubuTasks example in the fubumvc-contrib project solves this problem by starting a new transaction once the existing transaction is committed. Here is the source for FubuTask’s NHibernateUnitOfWork. I have talked to Chad Myers about this implementation and he has moved away from the idea of handling rollback in general. In any event, I don’t like the idea of starting a new transaction because I don’t think there should be one transaction per request. At the same time, I am preventing the developer from using my unit of work for more than one transaction. At least for now, opening a new transaction is a YAGNI for me. What do you think?

The full source code with these changes are available in the mvbalaw-commons project here.

Tags:

kick it on DotNetKicks.com

Wednesday
Oct072009

Bootstrapping NHibernate with StructureMap

Jeremy Miller asked me to help him create a canonical example of bootstrapping NHibernate using StructureMap. This is not that example. Hopefully, it will provide a starting point of discussion and, with your feedback, we will be able to create that example together.

Many examples on configuring NHibernate depend on some library such as FluentNHibernate or include additional concepts such as Repositories. While we use FluentNHibernate and Repositories to interface with the database, I did not want to complicate the example with these concerns. I did not want to preclude their addition, either.

NHibernate Registry

I have encapsulated the NHibernate configuration in a StructureMap Registry. It makes the following available:

  • NHibernate.Configuration as a Singleton
  • ISessionFactory as a Singleton
  • ISession scoped to Hybrid (HttpContext, if available, falling back to Thread)
  • IUnitOfWork scoped to Hybrid, a light-weight container for ISession (more on this later)
  • IDatabaseBuilder, a utility class to create the database using SchemaExport and populate it with initial data.

That’s it. If you want to create your own ISession (for example, to use in an integration test), then you request the ISessionFactory and call the OpenSession() method.

Here is the NHibernateRegistry class that provides the Configuration, ISessionFactory, ISession, and IUnitOfWork:

using NHibernate;
using NHibernate.ByteCode.Castle;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernateBootstrap.Core.Domain;
using StructureMap.Attributes;
using StructureMap.Configuration.DSL;
using Environment=NHibernate.Cfg.Environment;

namespace NHibernateBootstrap.Core.Persistence
{
    public class NHibernateRegistry : Registry
    {
        public NHibernateRegistry()
        {
            var cfg = new Configuration()
                .SetProperty(Environment.ReleaseConnections, "on_close")
                .SetProperty(Environment.Dialect, typeof(SQLiteDialect).AssemblyQualifiedName)
                .SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName)
                .SetProperty(Environment.ConnectionString, "data source=bootstrap.sqlite;Version=3")
                .SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)
                .AddAssembly(typeof(Blog).Assembly);

            var sessionFactory = cfg.BuildSessionFactory();

            ForRequestedType<Configuration>().AsSingletons().TheDefault.IsThis(cfg);

            ForRequestedType<ISessionFactory>().AsSingletons()
                .TheDefault.IsThis(sessionFactory);

            ForRequestedType<ISession>().CacheBy(InstanceScope.Hybrid)
                .TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());

            ForRequestedType<IUnitOfWork>().CacheBy(InstanceScope.Hybrid)
                .TheDefaultIsConcreteType<UnitOfWork>();

                ForRequestedType<IDatabaseBuilder>().TheDefaultIsConcreteType<DatabaseBuilder>();
        }
    }
}

Unit Of Work

Recently, I have been in several discussions regarding what the Unit of Work’s (single) responsibility is. Per Martin Fowler’s definition, a Unit of Work “maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.” In practice, NHibernate’s ISession is a Unit of Work.

When I first created my example, I used the ISession directly, but I found myself writing the following code over and over again:

    var product = new Product {Name = "Apple", Category = "Fruits"};
    using (var session = _sessionFactory.OpenSession())
    using (var transaction = _session.BeginTransaction())
    {
        session.Save(product);
        transaction.Commit();
    }

When I really wanted to write this:

    var product = new Product {Name = "Apple", Category = "Fruits"};
    using (var unitOfWork = new UnitOfWork(_sessionFactory))
    {
        unitOfWork.CurrentSession.Save(product);
        unitOfWork.Commit();
    }

So, my Unit of Work is a simple wrapper that combines the ISession and ITransaction together.

using System;
using NHibernate;

namespace NHibernateBootstrap.Core.Persistence
{
    public interface IUnitOfWork : IDisposable
    {
        ISession CurrentSession { get; }
        void Commit();  
    }
}
using NHibernate;

namespace NHibernateBootstrap.Core.Persistence
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly ISessionFactory _sessionFactory;
        private readonly ITransaction _transaction;

        public UnitOfWork(ISessionFactory sessionFactory)
        {
            _sessionFactory = sessionFactory;
            CurrentSession = _sessionFactory.OpenSession();
            _transaction = CurrentSession.BeginTransaction();
        }

        public ISession CurrentSession { get; private set;}

        public void Dispose()
        {
            CurrentSession.Close();
            CurrentSession = null;
        }

        public void Commit()
        {
            _transaction.Commit();
        }
    }
}

I have heard the argument that this is not a real Unit of Work because it does not track the changes per Martin Fowler's definition. While I agree, I also believe that ISession is not just a Unit of Work either because it includes Get methods that have nothing to do with the Unit of Work. Also, best practices dictate that NHibernate not use implicit transactions. ISession can not be a Unit of Work without requiring the developer to interact with ITransaction. So, my compromise is to create a simple interface that melds NHibernate’s ISession with its ITransaction. I have heard other names for this class such as TransactionBoundary, but that doesn’t sound right to me. I am open to other suggestions. However, please don’t get caught up in the naming or I’ll be forced to change it to an unpronounceable symbol called “The class formerly known as Unit of Work”.

NHibernateModule

Finally, in order to manage the Unit of Work for web applications, I created an HttpModule called NHibernateModule that creates a Unit of Work in the Begin_Request event handler and disposes of it in the End_Request event handler.

using System;
using System.Web;
using NHibernateBootstrap.Core.Persistence;
using StructureMap;

namespace NHibernateBootstrap.Web
{
    public class NHibernateModule : IHttpModule
    {
        private IUnitOfWork _unitOfWork;

        public void Init(HttpApplication context)
        {
            context.BeginRequest += ContextBeginRequest;
            context.EndRequest += ContextEndRequest;
        }

        private void ContextBeginRequest(object sender, EventArgs e)
        {
            _unitOfWork = ObjectFactory.GetInstance<IUnitOfWork>();

        }

        private void ContextEndRequest(object sender, EventArgs e)
        {
            Dispose();
        }

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

NHibernateBootstrap Source Code and Tests

I have created a Google Code project called mvbalaw-commons with the code for NHibernateBootstrap among other things. You can browse the code here or check it out from here.

The sample application uses SQLite. So, the only external requirement is that you have installed ASP.NET MVC in order to run the web application. You will need Ruby and Rake to run the build file. See the README.TXT in the root of the NHibernateBootstrap file for more information getting it up and running.

Note: This example requires a build of StructureMap 2.5.4 after revision 262 which changes “the concrete class behavior so that it can still build a concrete class that is not specified, but it doesn’t get into the GetAllInstances()” per the check-in comment. Hopefully, there will be a new release of StructureMap soon. Until then, feel free to use the StructureMap dll in this project which was built from trunk (revision 263).

NHibernateBootstrap includes four projects:

  • NHibernateBootstrap.Core – fully functional domain and persistence classes to demonstrate NHibernate.
  • NHibernateBootstrap.Tests – integration tests around CRUD operations for a Product class.
  • NHibernateBootstrap.Tests.Environment – a single test that calls ObjectFactory.AssertConfigurationIsValid() to ensure that StructureMap is configured correctly.
  • NHibernateBootstrap.Web – an ASP.NET MVC 1.0 application with a Product CRUD controller.

The sample application bootstraps NHibernate, tests a ProductController, and provides full CRUD operations for a Product through an ASP.NET MVC web application.

In order to improve accessibility, I based my sample application on the one in the Getting Started Guide on NHibernate Forge which originally came from Gabriel Schenker’s excellent NHibernateFAQ series of blog posts.

Also, I started with Ayende’s NHibernate Unit Testing example to get familiar with interacting with SQLite. I left his example in the BlogTestFixture class in the NHibernateBootstrap.Tests project.

So what do you think? You can leave comments here or it might be better to move the discussion over to a discussion thread that I started in the StructureMap Google group to get more people involved.

Tags: ,

kick it on DotNetKicks.com

Tuesday
Oct062009

Code Snippets Using SyntaxHighlighter on SquareSpace

So, I didn’t expect to return to blogging with such a cliche, but I couldn’t find this information anywhere else. So, here’s how to set up SyntaxHighlighting for a blog on SquareSpace.

Here is an example code snippet created using Alex Gorbatchev’s Syntax Highlighter tool:

namespace StarterProject.Core
{
    public class HelloWorld
    {
        public string Speak()
        {
            return "Hello, World!";
        }
    } 
}

It uses a series of javascript libraries and CSS styles to render code blocks in modern browsers.

Scott Hanselman’s blog post, Best Code Syntax Highlighter for Snippets in your Blog. explains how Syntax Highlighter works.  He even explains how to use it with PreCode, a LiveWriter plug-in.

I host my blog at SquareSpace, but could not find information on using Syntax Highlighter with it.  There is documentation on adding your own javascript and how to use Google Analytics.  Between these two pages, I was able to add the configuration necessary to integrate Syntax Highlighter with my blog.

First, login to your SquareSpace website.  Then, under the Website Management menu, there is a menu called Data & Media.  Select the File Storage submenu.  Create a folder called scripts and another one called styles.  These folders will be available to your web pages as /storage/scripts and /storage/styles, respectively.  Download and unzip the Syntax Highlighter folder.  Use the Upload Files button on the File Storage page to upload the contents of the scripts and styles folders to the new folders you just created at SquareSpace.

Under the Website Management menu, there is another menu called Structure.  Select the Website Settings submenu item.  On the Website Settings page, there is another menu bar.  Select the Code Injection menu item which brings up a drop-down menu for the Injection Region and a textarea for the HTML code.  Add the following code (you can cut and paste it from here) to the Extra Head Code (within <head> Tag) injection region:

<script type="text/javascript" src="storage/scripts/shCore.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushBash.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushCpp.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushCSharp.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushCss.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushDelphi.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushDiff.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushGroovy.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushJava.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushJScript.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushPhp.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushPlain.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushPython.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushRuby.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushScala.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushSql.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushVb.js"></script>
<script type="text/javascript" src="storage/scripts/shBrushXml.js"></script>
<link type="text/css" rel="stylesheet" href="storage/styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="storage/styles/shThemeDefault.css"/>
<script type="text/javascript">
    SyntaxHighlighter.config.clipboardSwf = 'storage/scripts/clipboard.swf';
    SyntaxHighlighter.all();
</script>

I noticed some issues with preview in LiveWriter and even previewing the blog posts before publishing them, but it looked right for me once I published the blog entries.  For reference, I installed Syntax Highlighter version 2.0.320 and PreCode version 5.0.1.

You may also want to adjust the width of your content column to accommodate wider code snippets.  If so, I recommend this page, Adjusting Column Widths.