Thursday, July 29, 2010

Dependency Injection using Munq

I'm in the middle of a building a WCF Rest(ful) web service and I want to use some form of DI. I've used Daniel Cazzulino's Funq on a previous project and although it doesn't necessarily provide all the bells and whistles or have the market-share of some of the other frameworks it is extremely fast, easy to set up, and has a simple lambda-based configuration. It also comes with an awesome set of videos documenting the construction process, worth looking at just to see a developer doing some great TDD.

For a WCF or MVC project there are some constraints that would make Funq a bit more interesting to set up. Fortunately there is a derivative of Funq, Matthew Dennis's Munq project (example usage for ASP.NET MVC is available on CodeProject) that is intended for this purpose.

Using Munq for WCF differs from the ASP.NET MVC configuration example and I went through the exercise long enough ago that the only evidence I have is an old project that I've been trawling through to try and figure out how it is all wired together. I do recall following someone else's instructions (Oran Dennison's I think) for implementing a different IOC framework with WCF and modifying it for Munq. This particular blog entry is at least in part to avoid having go through the same head scratching exercise the next time I want to use DI in a WCF service.

My WCF service will be hosted in IIS and I created the initial project using the WCF REST Service Application template. The idea is to allow Munq to serve up instances of the service and Microsoft provides a convenient hook for doing this using the IInstanceProvider interface.

1  public class MunqInstanceProvider : IInstanceProvider
2  {
3
4      private readonly Type serviceType;
5
6      public MunqInstanceProvider(Type serviceType)
7      {
8          this.serviceType = serviceType;
9      }
10
11 #region Implementation of IInstanceProvider
12
13      /// <summary>
14     /// Returns a service object given the specified <see cref="T:System.ServiceModel.InstanceContext"/> object.
15     /// </summary>
16      /// <returns>
17     /// A user-defined service object.
18     /// </returns>
19     /// <param name="instanceContext">The current <see cref="T:System.ServiceModel.InstanceContext"/> object.</param>
20      public object GetInstance(InstanceContext instanceContext)
21     {
22         return GetInstance(instanceContext, null);
23     }
24
25     /// <summary>
26     /// Returns a service object given the specified <see cref="T:System.ServiceModel.InstanceContext"/> object.
27      /// </summary>
28     /// <returns>
29     /// The service object.
30     /// </returns>
31     /// <param name="instanceContext">The current <see cref="T:System.ServiceModel.InstanceContext"/> object.</param><param name="message">The message that triggered the creation of a service object.</param>
32      public object GetInstance(InstanceContext instanceContext, Message message)
33      {
34         var instance = Global.Di.Resolve(serviceType);
35         return instance;
36     }
37
38     /// <summary>
39     /// Called when an <see cref="T:System.ServiceModel.InstanceContext"/> object recycles a service object.
40     /// </summary>
41     /// <param name="instanceContext">The service's instance context.</param><param name="instance">The service object to be recycled.</param>
42      public void ReleaseInstance(InstanceContext instanceContext, object instance)
43     {
44         // container disposes of instance?
45         //if (instance is IDisposable)
46         // ((IDisposable)instance).Dispose();
47      }
48
49     #endregion
50 }

That call to Global.Di.Resolve() is where Munq returns an instance of the service. Global.Di needs to be defined somewhere, I'll get to that in a bit. Having implemented IInstanceProvider I now need to provide a custom serviceBehavior using the IServiceBehavior interface for the service endpoint. The following code creates a new MunqInstanceProvider for each ChannelDispatcher endpoint.

Note ForAll() is an extension method not included in .NET but defined as you might expect. For an explanation as to why it wasn't included in the framework refer to Eric Lippert's blog. For a long time I assiduously used a foreach loop to perform some action on every item in a sequence. Recently I've been reading Effective C# (Covers C# 4.0): 50 Specific Ways to Improve Your C#. Item 8 suggests I should Prefer Query Syntax to Loops and I absolutely do.

1 public class MunqServiceBehavior : IServiceBehavior
2 {
3     #region IServiceBehavior Members
4
5     public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) {}
6
7     public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
8     {
9         var endpoints = from cd in serviceHostBase.ChannelDispatchers.Cast<ChannelDispatcher>()
10                 where cd != null
11                 from endpoint in cd.Endpoints
12                 select endpoint;
13
14         endpoints.ForAll(ep => ep.DispatchRuntime.InstanceProvider = new MunqInstanceProvider(serviceDescription.ServiceType));
15     }
16
17     public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) {}
18
19     #endregion
20 }

Web.config is used to wire this all together but in order to reference the custom behavior a Munq-specific BehaviorExtensionElement is required.

1  public class MunqInstanceProviderExtensionElement : BehaviorExtensionElement
2  {
3      public override Type BehaviorType
4      {
5          get { return typeof (MunqServiceBehavior); }
6      }
7
8      protected override object CreateBehavior()
9      {
10          return new MunqServiceBehavior();
11     }
12 }

The relevant section of Web.config is provided below and replaces the system.serviceModel section. Getting each element correct is important but the stumbling block for me was getting the service name correct and I couldn't figure out why none of my Munq classes were being hit.

1  <system.serviceModel>
2      <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
3                   multipleSiteBindingsEnabled="true" />
4       <services>
5           <service name="StillPearlingService.StillPearling" behaviorConfiguration="MunqServiceBehavior"></service>
6       </services>
7       <behaviors>
8          <serviceBehaviors>
9              <behavior name="MunqServiceBehavior">
10                  <MunqInstanceProvider />
11            </behavior>
12            <behavior name="">
13                <serviceMetadata httpGetEnabled="true" />
14                <serviceDebug includeExceptionDetailInFaults="false" />
15            </behavior>
16        </serviceBehaviors>
17     </behaviors>
18      <extensions>
19          <behaviorExtensions>
20              <add name="MunqInstanceProvider" type="StillPearling.IOC.MunqInstanceProviderExtensionElement, StillPearling, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
21          </behaviorExtensions>
22      </extensions>
23      <standardEndpoints>
24          <webHttpEndpoint>
25      <!--
26         Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
27         via the attributes on the <standardEndpoint> element below
28     -->
29              <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
30          </webHttpEndpoint>
31      </standardEndpoints>
32 </system.serviceModel>


So having completed the majority of the wiring there is still the small matter of declaring and instantiating the Munq DI container. This happens in Global.asax, along with registering other objects I want to wire into the container. In this case I have a Model class that I use for accessing a database. Within my service I declare a Model property with a public setter that is used as a hook for Munq to inject the correct Model object.

1  public class Global : HttpApplication
2  {
3      private static Logger logger = LogManager.GetCurrentClassLogger();
4      public static Container Di { get; private set; }
5
6      void Application_Start(object sender, EventArgs e)
7      {
8           logger.Info(() => "Application_Start");
9           Di = new Container();
10         RegisterInterfaces();
11         RegisterRoutes();
12     }
13
14     private static void RegisterInterfaces()
15     {
16         logger.Debug(() => "RegisterInterfaces");
17         Di.Register<IStillPearlingModel>(di => new Model());
18         Di.Register(di => new StillPearling { Model = di.Resolve<IStillPearlingModel>(), });
19     }
20
21     private static void RegisterRoutes()
22     {
23         // Edit the base address of Service1 by replacing the "Service1" string below
24         RouteTable.Routes.Add(new ServiceRoute("StillPearlingService", new WebServiceHostFactory(), typeof(StillPearling)));
25     }
26 }
27

Note this was all done using Munq 1.0 and Munq 2.0 has recently been released. I don't expect any issues transitioning to version 2.0 but I'll try to provide an update if there are any potholes to be avoided. If you've read this far I appreciate it and I would further appreciate feedback on what I'm doing wrong. Finally I apologise for any formatting issues with the code above - I'm still looking for a good encoding tool that works with blogger.

Thursday, July 22, 2010

First things first?

Clearly if I want to play with F# & ASP.NET MVC I should get the Visual Studio 2010 project template from Tomas Petricek. Then after installing in Visual Studio I get a new option to create a F# MVC Web Application. Mostly it just works but the reference in WebApplication.Core to the WebApplication.Data project needs to be updated for it to build. BTW, if you're looking for a quickstart C# MVC project check out Rob Conery's Tekpub MVC 2.0 Starter, it has an associated starter video available free from Tekpub. This is not that.

So what about MSpec? The latest release is available from TeamCity. I'm using ReSharper 5.1 so installing MSpec is just a matter of unblocking zip file (aargh), unzipping, pathing to unzipped location and running the appropriate batch file - & '.\InstallResharperRunner.5.1 - VS2010.bat'  (why are we still using batch files).

Now I have the pieces of the puzzle but I'm not entirely sure how I'm supposed to assemble them. Using a post from Elegant Code as a starting point I added a test project to my solution and copied Jan's sample into UnitTest1.cs. Visual Studio doesn't know what is [Subject("Making a customer preferred")] which is resolved by first creating a "libs" folder in my solution folder and adding Machine.Specifications.dll to it, then adding a reference to that dll to my test project. Then in the interests of seeing some actual output I need to flesh out the sample code with sufficient code to allow the test to compile:

1 [Subject("Making a customer preferred")]
2 public class when_a_regular_customer_is_made_preferred
3 {
4     Establish context = () =>
5     {
6        _order = new Order(new[] { new OrderItem(12),
7            new OrderItem(16) });
8        _totalAmountWithoutDiscount = _order.TotalAmount;
9
10         SUT = new Customer(new[] { _order });
11    };
12
13 Because of = () =>
14     SUT.MakePreferred();
15
16 It should_mark_the_customer_as_preferred = () =>
17     SUT.IsPreferred.ShouldBeTrue();
18
19 It should_apply_a_ten_percent_discount_to_all_outstanding_orders = () =>
20     _order.TotalAmount.ShouldEqual(_totalAmountWithoutDiscount * 0.9);
21
22     private static Customer SUT;
23
24     private static Order _order;
25     private static Double _totalAmountWithoutDiscount;
26 }
27
28 //
29 // Subject under test
30 //
31 public class Customer
32 {
33     private readonly List<Order> _orders;
34     public Boolean IsPreferred { get; private set; }
35
36    public Customer(IEnumerable<Order> orders)
37     {
38         _orders = new List<Order>(orders);
39     }
40
41 public void MakePreferred()
42 {
43     if (IsPreferred)
44         return;
45
46    IsPreferred = true;
47     _orders.ForEach(order => order.ApplyDiscount(10));
48 }
49 }
50
51 public class Order
52 {
53     private OrderItem[] orderItems;
54
55     public Order(OrderItem[] orderItems)
56     {
57         // TODO: Complete member initialization
58         this.orderItems = orderItems;
59     }
60     public double TotalAmount { get; set; }
61     public double ApplyDiscount(int percentDiscount)
62     {
63         return TotalAmount*(100 - percentDiscount)/100;
64     }
65
66 }
67
68 public class OrderItem
69 {
70     private int p;
71
72     public OrderItem(int p)
73     {
74         // TODO: Complete member initialization
75         this.p = p;
76     }
77 }

Now I can run the unit test using ReSharper and sure enough I get the correct output:
Making a customer preferred, when a regular customer is made preferred
    » should mark the customer as preferred
    » should apply a ten percent discount to all outstanding orders
Obviously this is a contrived example but I have established that I can run MSpec tests in my solution. If at some point it no longer works I know it's my bad.

Wednesday, July 21, 2010

Exploring the ecosystem

There are a number of things on my todo list, including F#, ASP.NET MVC, MSpec, Munq, Moq and maybe an alternative markup engine such as StringTemplate. My other todo list includes HTML5, PhoneGap, and iPhone development. My Amazon order showed up a couple of weeks ago including Douglas Crockford's excellent JavaScript: The Good Parts, Building iPhone Apps with HTML, CSS, and JavaScript, and Expert F# 2.0.

I will admit to being a long time fan of JavaScript and it's nice to see it finally getting mind-share. Crockford's book is dense and contains a lot of good stuff and as a consequence I'm still working my way through it. I'm also still not entirely comfortable with the idea of modifying the prototypes of the predefined objects such as Object, String, etc, guess I'll reserve judgment until I'm finished reading.

As part of getting back up to date with JavaScript I've also started using QUnit to unit test a module I'm writing for accessing Safari's SQLite database. There are some excellent links here, and here (blog comments are particularly useful) re using QUnit for testing asynchronous calls. Calls to SQLite are all based on callbacks so being able to unit test asynchronously is essential.

Below is a very early example of the database access code I'm working on. Clearly I've got a long way to go but it's a start and demonstrates the module pattern I use to hide the internals. I plan to replace the database version update code so I can seamlessly update the database when upgrading the application version. I'm still trying to get my head around the K&R indenting which is now the most common indenting style in JavaScript. Having coded C++ for many years and subsequently C# I'm pretty committed to the Allman style indenting. But some of the reasons for using Allman style are no longer relevant and with LINQ in particular it is difficult (impossible?) to use Allman style consistently. In JavaScript there is at least one situation where using Allman style will result in code breaking. Douglas Crockford mentions this in his book:

I always use K&R style, putting the { at the end of a line instead of the front, because it avoids a horrible design blunder in JavaScript's return statement.
To really nail my Allman addiction I read a tweet recently from I think one of either Rob Conery or Dave Ward to the effect that JavaScript written using Allman was not to be trusted (hmm maybe it was Gruber, can't find the reference). So I guess my first job is to reformat using the new hotness and once again feel like I am worthy.

BTW, if anyone knows a good code formatter for Blogger I would be grateful, the one I used to produce the code below is not quite there.

1 var db = function ()
2 {
3 /**
4 * private
5 */
6 var CURRENT_VERSION = 1.01;
7 var shortName = 'rtt';
8 var version;
9 var displayName = 'Red Tomato Timesheet';
10 var maxSize = 65536; // bytes
11 var database;
12
13 var init = function(transaction) { console.info("Updating database to version 1"); };
14
15 var success = function(){ console.info("success");};
16 var failure = function(error){ console.info("fail: " + error);};
17
18 var up101 = function(t)
19 {
20     var sql = "\
21         CREATE TABLE projects (\
22             id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\
23             name TEXT NOT NULL,\
24             description TEXT NOT NULL);";
25      console.info("sql:" + sql);
26      t.executeSql( sql, [], function(){ console.info("version 1.0 -> 1.01 success");});
27 };
28
29 var updateVersion = function()
30 {
31     console.info("Updating database to current version " + CURRENT_VERSION);
32     try
33      {
34         switch(version)
35         {
36             case '' : database.changeVersion('', '1', init, failure, success);
37             case "1" : database.changeVersion("1", "1.01", up101, failure, success);
38         }
39     }
40     catch (e)
41     {
42         console.error("database.changeVersion failed " + e.message);
43      }
44 };
45
46 return {
47
48     /**
49     * open database
50     */
51     open: function()
52     {
53          database = openDatabase(shortName, "", displayName, maxSize);
54         version = database.version;
55         console.info("database: " + displayName + " " + version);
56         if (version != CURRENT_VERSION)
57         {
58             updateVersion();
59         }
60     },
61
62      /**
63     * isOpen
64     */
65     isOpen: function()
66     {
67         return null != database;
68     },
69
70     /**
71     * version
72     */
73     version: function()
74     {
75         return version;
76     },
77 }
78
79 } ();
80
  

Wednesday, June 23, 2010

Been at the coalface

Wow, it's been more than a year, time flies like the wind (fruit flies like bananas). Working is good and over the past year I've been hands on with Windows Mobile 6, developing a mobile application for Powerco for field staff to test and record results for power industry assets like power poles, transformers, fuses, switches. Kind of weird to be back writing Windows Forms based apps after focusing on web apps for a long time and working with the shrunken version of .NET had some frustrations but I'm reasonably happy with the end result. Of course 20/20 hindsight is a wonderful thing and if I had it to do over again I would inevitably make some different choices.


I like LINQ, DTO's, PowerShell ISE, Visual Studio 2010, and Scrum. .netTiers not so much. MSBuild (including the MSBuild Community Tasks and the MSBuild Extension Pack) was awesome for patching .netTiers code generation issues and for automating builds right through to outputting .msi installers for each of the test, staging, and production environments. Getting consistent installs was a huge benefit and automating all the little tweaks required to get the .netTiers output to build reduced the code generation time from about a day down to just a few minutes.


I'm not dissing .netTiers particularly, it's just prior to automating the tweaks they had all been done by hand with associated risk of transcription errors plus the time factor required. Many of the tweaks could also be applied directly to the templates so the code was generated correctly in the first place. Taking a long and often frustrating exercise and automating it meant we could effect database changes quickly and were far less concerned about having to regenerate the code if something wasn't quite right. Overall .netTiers is a fairly hefty tool and I still find it frustrating getting it to produce the desired results if the desired results don't conform to the standard output. 


I've also been doing some work for base 2 on their task management application. That app uses SubSonic for data access and I really like the lighter weight of the tool. Generating code is fast and largely hassle-free. Of course it attempts to do a lot less than .netTiers which generates multiple data/service layers and I suppose each is a reasonable choice for its respective domain. Actually .netTiers was already part of the ecosystem when I joined that project and I can't imagine ever prescribing it for future work.

Wednesday, March 18, 2009

Software Craftsmanship

I'm a fan and subscriber of InfoQ. Lots of good stuff, a bit of dross, and the occasional jewel. The latest newsletter included news of the Software Craftsmanship Manifesto: A Call to Arms.



As aspiring Software Craftsmen we are raising the bar of professional software development by practicing it and helping others learn the craft. Through this work we have come to value:



  • Not only working software, but also well-crafted software

  • Not only responding to change, but also steadily adding value

  • Not only individuals and interactions, but also a community of professionals

  • Not only customer collaboration, but also productive partnerships


That is, in pursuit of the items on the left we have found the items on the right to be indispensable.



© 2009, the undersigned. this statement may be freely copied in any form, but only in its entirety through this notice.



History Lesson


Many years ago, somewhat fresh out of school, I figured I was doing ok as a coder. The work I was involved in was generally interesting and I felt I was doing a pretty good job. That all changed dramatically a short time later when I was given the responsibility for designing and constructing from scratch the debit card PIN encryption and verification infrastructure for a New Zealand household-name financial services provider. This involved writing C++ code to interface to the hardware encryption module locked into a rack in the computer room and communicating with PIN Pads and Encoders attached to computers in the branch network, plus a little GUI development to drive it all. These were the days before the emergence of Web Services and WCF; Windows NT was the target platform for both server and workstation — there was a lot of low-level boilerplate that just didn't exist. Ultimately it all worked well, I was reasonably happy with the resulting code, and the system provided many years of reliable, low-maintenance service.


However during the project I found myself in a deep hole with respect to a core aspect of the design. I was working for a vendor organisation at the time and when I asked for some assistance the silence was unnerving. I suspect there weren't any people in the organisation with relevant experience but what I needed was more peer review than technical assistance. Fortunately I'm not shy about asking for help when I need it. I finally got to sit down with another developer who pointed me towards the newly minted Component Object Model (COM).


Books


I started reading and haven't really ever stopped. One of the early books I read was Scott Meyers awesome Effective C++. Finding out how many things I had been doing incorrectly was painful but enlightening and really highlighted to me what a challenge it is to produce good quality C++.


Eric Meyer's Eric Meyer on CSS was another watershed moment for me. After an initial foray into writing code for the Web I finally began to understand how it could work. Lets face it, up until recently everything we've done on the Web is a hack. We pretend the browser is just a dumb terminal and not a sophisticated development platform in its own right. With Web 2.0, AJAX, and REST we are beginning to see the browser platform being taken seriously with good separation between client-side and server-side.


Jeffrey Friedl's excellent Mastering Regular Expressions is another great book, David Flanagan's JavaScript: The Definitive Guide, Fowler's Patterns of Enterprise Application Architecture, Andrew King's Speed Up Your Site, Uncle Bob's (& son) Agile Principles, Patterns, and Practices in C#, Joe Celko's SQL Programming Style. Just a few of many great and often extremely readable tomes informing and affording better software craftmanship.


Voodoo


Having personally witnessed the likes of copy-paste coding, superstitious code, and voodoo chicken coding, I've often found myself trying to raise the standard of the development efforts in which I've been involved. But I've also frequently found myself working without peer-review. It is that latter situation where the right book can be valuable, far more so than wading through pages of Google search results trying to identify the one nugget of information I'm looking for.


I've rambled on long enough. Read the article, sign the manifesto, join the LinkedIn group, and raise the bar.

Thursday, March 12, 2009

NHibernate.Linq

Hiatus


Right now I need to park my attempts at configuration of a new Windows Server 2008 r2 Core web server. I've effectively managed to hose my configuration, I hope temporarily, in the process of applying a security template using secedit.exe. Not one of my best moments, particularly when I've had something similar occur previously. Unfortunately there just isn't a whole lot of info I can find about using secedit but I'll keep all those details for another post.


NHibernate


Having used the Java Hibernate ORM tool previously, plus having an interest in LINQ and wanting to cut some actual code, I figured I would kill three birds using NHibernate.Linq. Of course once I started googling it became apparent that there are many interesting things occuring in the Alt.Net space, enough to get happily side-tracked for some time.


I eventually found my way back and followed these instructions to build NHibernate from the latest subversion source. The mystery of the missing assemblyinfo.cs files was quickly solved although I did have to install NAnt and modify the default.build NAnt file to correctly generate the missing file for the NHibernate.ByteCode.Spring project. I think the entry had been removed to decouple NHibernate from Spring but the work may not have been complete at the point that I retrieved the source. The source has a comprehensive test suite which, apart from highlighting issues using NHibernate with my PostgreSQL database, is also a great starting point for information about using NHibernate.


PostgreSQL


As mentioned above, I'm using Postgres which happens to be installed on my MacBook Pro. I wanted to run the test suite against it from my Vista VM. Connecting to Postgres was actually pretty straight forward. I created a database user nhibernate with a long random password (using uuidgen) and modified the provided Postgres template, renaming it to hibernate.cfg.xml (see below). Apart from setting the appropriate values for the user credentials and server, the connection string in the template incorrectly specified "Initial Catalog" — this needed to be changed to "Database". The Postgres driver is provided by the mono project which also contains good information about the connection string parameters. Two assemblies are required, mono.security.dll, and the driver itself Npgsql.dll. Once these things are in place, and assuming you already have the nunit framework installed, the test suite runs quite happily against the Postgres database. A small percentage of tests fail, typically due to some feature difference between the target SQLServer database and Postgres, a good way to highlight those things that might bite later.



<?xml version="1.0" encoding="utf-8"?>
<!--
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it
for your own use before compile tests in VisualStudio.
-->
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="NHibernate.Test">
<property name="connection.driver_class">NHibernate.Driver.NpgsqlDriver</property>
<property name="connection.connection_string">
Server=mbp;Database=nhibernate;User ID=nhibernate;Password=D4F52CC8-5603-4C84-9147-3CC602EF359A;
</property>
<property name="dialect">NHibernate.Dialect.PostgreSQLDialect</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
</session-factory>
</hibernate-configuration>

NHibernate.Linq


NHibernate.Linq is part of the NH Contrib project and the source is available from subversion. I replaced the NHibernate.dll with the one generated above. The test suite uses the NorthWind database so no joy testing against Postgres. I have SQLExpress installed in my Vista VM and with some jiggery pokery the tests will run successfully. First allow the user Full control on folder C:\SQL Server 2000 Sample Databases (or second in the event that attempting to attach the NorthWind database results in an error 5 exception). After starting SQLExpress if it isn't already running, it's necessary to attach the NorthWind database using the sp_attach_db stored procedure. And might as well create the Test database that is also required by the test suite.


By default accessing SQLExpress is limited to the Shared Memory protocol (some info and much joy can be found at SQL Server 2005 SQLExpress error: ...provider:Named Pipes Provider, error 40 - Could not open connection to SQL Server — fortunately I was already familiar with the issue, others obviously weren't so lucky). The NHibernate.Linq test suite uses Named Pipes for connecting to the database and will choke if the protocol isn't enabled. Enabling Named Pipes is straight forward using SQLServer Configuration Manager and requires the service to be restarted.


The other trap to be aware of is the surface area configuration which needed to be modified to add my user as an administrator and ensure remote connections via named pipes are enabled. This is managed by the SQL Server 2005 Surface Area Configuration tool.


app.config file for the test suite also needs to be modified to connect to SQLExpress:



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Test"
connectionString="Data Source=.\SQLExpress;initial catalog=Test;Integrated Security=SSPI"/>
<add name="Northwind"
connectionString="Data Source=.\SQLExpress;Initial Catalog=NorthWind;Integrated Security=SSPI"/>
</connectionStrings>
</configuration>

Running


To actually run the tests, the NHibernate.Linq.Test project needs to be the Startup Project and the project properties modified to use NUnit for testing.


Finally the tests run successfully. 46 of the tests are ignored which indicates there is some work yet to be completed but at least it is obvious where the work is required.