Dependancy Injection With RemObjects SDK

RemObjects SDK is a comprehensive remoting framework which I’ve used in a number of projects over the years. It has support for a number of platforms, including .Net and Delphi among others, and provides a comprehensive feature set from encryption to load balancing.

Injection Points

There are a few points we could use to do dependancy injection when using RemObjects; I have highlighted a couple below

Overriding Activate

Each service implemented in RemObjects inherits from RemObjects.SDK.Server.Service which has a method called Activate. This is called before a call is pushed through a service in order to carry out any initialization required.

using System.Collections.Generic;

namespace TestService
{
  using System;
  using RemObjects.SDK;
  using RemObjects.SDK.Types;
  using RemObjects.SDK.Server;
  using RemObjects.SDK.Server.ClassFactories;

  [RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
  [RemObjects.SDK.Server.Service(Name = "TestService", InvokerClass = typeof(TestService_Invoker), ActivatorClass = typeof(TestService_Activator))]
  public class TestService : RemObjects.SDK.Server.Service, ITestService
  {
    private System.ComponentModel.Container components = null;
    private ILogger logger;
    public PingService() :
      base()
    {
      this.InitializeComponent();
    }
    private void InitializeComponent()
    {
    }
    protected override void Dispose(bool aDisposing)
    {
      if (aDisposing)
      {
        if ((this.components != null))
        {
          this.components.Dispose();
        }
      }
      base.Dispose(aDisposing);
    }
    public override void Activate(Guid aClientID)
    {
      base.Activate(aClientID);
      //inject here...
      logger = App.Get<ILogger>();
    }
    public override void Deactivate(Guid aClientID)
    {
      base.Deactivate(aClientID);
      //deinit here...
    }
    public virtual bool DoSomething(string msg)
    {
      try
      {
        //service implementation
      }
      catch (Exception ex)
      {
        logger.Log(LogLevel.ERROR, "Error in DoSomething: " + ex.Message);
        return false;
      }
    }
  }
}

Service Activator

In order to instantiate a service, RemObjects uses generated activator classes. This is the perfect point at which to inject whatever you need to as this is where the instance of the service is first created.

[RemObjects.SDK.Activator()]
  [System.Reflection.ObfuscationAttribute(Exclude = true, ApplyToMembers = false)]
  public class TestService_Activator : RemObjects.SDK.Server.ServiceActivator
  {
    public TestService_Activator() :
      base()
    {
    }
    public override RemObjects.SDK.IROService CreateInstance()
    {
      //call to our service locator
      return App.Get<PingService>();
    }
  }

The big downside to this is that this code gets generated every time you edit the service in the Service Builder application.

The App object above simply provides us with access to our chosen method of handling dependency resolution. In this case it would be wrapping access to the Ninject kernel configured for the application.

Decisions, Decisions

My preference is to do the injection in the Service Activator as this allows you to clearly define what dependencies a service has by listing them as part of its constructor.

If instead you were to override the Activation method, it becomes less clear what objects the service depends on as the details are lost in a method call, rather than being part of the class declaration.

System.Data.SQLite And 64 Bit Operating Systems

An old customer surfaced recently, wondering why a new installation of an old .Net WinForms application I wrote wouldn’t work on their shiny new 64 bit system.

As it turns out, I used SQLite for this particular project as the data storage engine. Because this is a managed .Net wrapper around the native sqlite library, it was causing problems when trying to load the 32 bit version of the library on a 64 bit system.

A Quick Fix

Fortunately it’s quite straight forward to force an assembly to run in a 32 bit version of .Net, regardless of the host platform as there is a flag in the assembly that will define this.

In Visual Studio this can be found on the project properties page under the ‘Build’ tab.

Platform Target

Setting ‘Platform Target’ to x86 will force the assembly to be run under the 32 bit .Net framework.

This can also be set using the command line corflags utility:

corflags /32BIT+ dotnetapp.exe

The Correct Fix

Obviously the correct thing to do would be to detect the OS version on install and use the correct version of the SQLite wrapper, but the above serves as a quick fix to get them up and running.

Unit Testing With NHibernate And SQLite

Good unit tests should, among other things, be easily repeatable and independent. If you’re testing against a full blown MySQL or MSSQL server it can become difficult to easily repeat a test if you rely on certain records holding certain Ids, and the independent nature of the test is impacted as it’s not well isolated from a specific server.

Testing against an SQLite database can help alleviate these issues as the flatfile database can be created and thrown away after each test, making it easy to repeat a test on fresh data each time.

So let’s look at how to go about setting this up.

The Standard SessionFactory

In order to get an NHibernate session normally in my application, I use a provider class to provide access to a SessionFactory:

  public static class SessionFactoryProvider
  {
    private static ISessionFactory sessionFactory;
    private static Object lockObj = new Object();

    private static void BuildSessionFactory()
    {
      string connStr = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

      sessionFactory = Fluently.Configure().
        Database(MsSqlConfiguration.MsSql2005.ConnectionString(connStr)).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MvcApplication>()).
        BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
      if (sessionFactory == null)
        lock(lockObj)
          if (sessionFactory == null)
            BuildSessionFactory();

      return sessionFactory.OpenSession();
    }
  }

This will normally live in the assembly that contains all the data access logic, and will used through dependency injection.

The Test SessionFactory

To get an SQLite database for testing, we need to create it in a slightly different way, specifying a filename for SQLite to use, and providing a way to tear it down after use:

namespace DITests
{
  public static class TestSessionFactoryProvider
  {
    private static ISessionFactory sessionFactory;
    private static string dbFile;

    private static string GetDbFileName()
    {
      var path = Path.GetFullPath(Path.GetRandomFileName() + ".Test.db");
      if (File.Exists(path))
      {
        File.Delete(path);
      }
      return path;
    }

    private static void BuildSessionFactory()
    {
      dbFile = GetDbFileName();

      sessionFactory = Fluently.Configure().
        Database(SQLiteConfiguration.Standard.UsingFile(dbFile).ShowSql()).
        ExposeConfiguration(c =>
        {
          c.Properties.Add("hbm2ddl.keywords", "none");
          c.Properties.Add("hbm2ddl.auto", "create");
        }).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>()).
        BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
      if (sessionFactory == null) BuildSessionFactory();
      return sessionFactory.OpenSession();
    }

    public static void Teardown()
    {
      if (sessionFactory != null)
      {
        sessionFactory.Dispose();
        sessionFactory = null;
      }

      if (File.Exists(dbFile))
      {
        File.Delete(dbFile);
      }
    }
  }
}

Something To Test

Now that the test session factory is setup, we need something to test, so here’s a very simple user class, mapping and repository:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NHibernate;
using NHibernate.Linq;

namespace MVC3DI.Models
{
  public class User
  {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
  }

  public class UserMap : ClassMap<User>
  {
    public UserMap()
    {
      Id(c => c.Id);
      Map(c => c.Name);
      Map(c => c.Age);
    }
  }
  public class UserRepository
  {
    ISession session;
    private IQueryable<User> Users
    {
      get { return session.Query<User>(); }
    }

    public UserRepository(ISession session)
    {
      this.session = session;
    }

    public IList<User> GetUsers()
    {
      using (session.BeginTransaction())
      {
        var query = from c in Users select c;
        return query.ToList();
      }
    }

    public void Save(User user)
    {
      using (ITransaction t = session.BeginTransaction())
      {
        session.Save(user);
        t.Commit();
      }
    }
  }
}

The Test

And finally, we can setup some tests to run. Because the user repository takes an ISession in its constructor, we can easily change which SessionProviderFactory we’re using, allowing us to drop in our test one in order to test against SQLite:

using System;
using System.Collections.Generic;
using NUnit.Framework;
using MVC3DI.Models;

namespace DITests
{
  [TestFixture]
  public class HireContractDALTests
  {
    UserRepository repo;

    [SetUp]
    public void Setup()
    {
      repo = new UserRepository(TestSessionFactoryProvider.OpenSession());

      //insert some test checks
      var users = new List<User>(){
        new User(){ Name = "Frank", Age = 24 },
        new User(){ Name = "Bob", Age = 22 },
        new User(){ Name = "Bert", Age = 30 },
      };
      users.ForEach(p => repo.Save(p));
    }

    [TearDown]
    public void TearDown()
    {
      TestSessionFactoryProvider.Teardown();
    }

    [Test]
    public void TestTryLoadUsers()
    {
      var users = repo.GetUsers();
      Assert.AreEqual(3, users.Count);
      Assert.AreEqual("Frank", users[0].Name);
      Assert.AreEqual("Bob", users[1].Name);
      Assert.AreEqual("Bert", users[2].Name);
    }
  }
}

This is a pretty straight forward test which fires up the database, creates a few records, and then reads them back in order to verify that they were saved correctly.

Limitations

The big limitation with this method is that you can only test code that is database agnostic. This should be fine if you’re only strictly accessing records through NHibernate as that will take care of creating the correct SQL for you, but if you write any SQL yourself with keywords specific to a certain provider, it will quickly fall over when run against SQLite.

There’s not a whole lot that can be done about this; you could extract the database specific functions to a more specific implementation, but then that would need testing too, which you can only do against the database it’s targeted at, so that seems a little pointless. Which leaves you with either not testing that code or not writing it in the first place!

Summary

There is some debate as to the value of testing at the database level, especially when you’re not testing against the database that will be used in production, but personally I think it can still be useful in verifying that mappings are working correctly and to test any basic logic that may live down at that level.

Using SQLite as a replacement during testing ensures your tests will run quickly and be independant of any outside requirements. Whilst the downside to this is that you can’t test vendor specific SQL with this method, it’s generally best to avoid this anyway when using an ORM such as NHibernate.

Jquery Auto-Complete with ASP .Net MVC

I’ve been doing a lot of work with Microsoft’s MVC Framework over the past few weeks, having been a convert to the MVC way of doing things for some time.

A customer requested a feature to select an item using a popup form that would allow the user to search and select the relevant entry. I decided this could be achieved in a less obtrusive manner by using an auto-complete field a la google suggest.

Google Auto Complete

The Jquery UI library features a number of useful UI elements, with an auto-complete widget among them, so this is what I decided to use.

The MVC Controller

We’ll start off implementing the backend, which will be an action in a controller that will return a JSON result.

public ActionResult Customers(string term)
{
  List<Customer> list = new List<Customer>{
    new Customer(){AccountName = "Test Company 1", AccountNum = "1234"},
    new Customer(){AccountName = "Another Test 2", AccountNum = "1235"},
    new Customer(){AccountName = "Another Company 3", AccountNum = "1236"},
    new Customer(){AccountName = "Testing Account 4", AccountNum = "1237"},
    new Customer(){AccountName = "Late Company", AccountNum = "1238"},
    new Customer(){AccountName = "Test Company", AccountNum = "1239"},
  };
  return Json(list.Where(c => c.AccountName.Contains(term)));
}

In this case I’m just putting together a list of mock data and returning it as a JSON result using MVC’s built in Json encoding functionality.

The only other thing to note here is the function argument term which contains the search term that will be entered into the auto-complete box. This is what will be used to filter our data.

Obviously in an actual implementation we’d be calling out to our data access layer to do the querying, but for the sake of example I’ll be keeping this simple.

Jquery UI

Now that we have some data to work with, let’s pull it down and display it. First the HTML:

<label for="customer_search">Customer:</label>
<input id="customer_search" type="text" />

And then the JavaScript:

$(document).ready(function() {
  $('#customer_search').autocomplete({
    source:'/POD/Customers',
    minLength: 3,
    select : function(event, ui){
      $( "#customer_search" ).val( ui.item.AccountName );
      //here we might want to store ui.item.AccountNum etc...
      return false;
    },
    focus: function( event, ui ) {
      $( "#customer_search" ).val( ui.item.AccountName );
      return false;
    },
  }).data( "autocomplete" )._renderItem = function( ul, item ) {
    return $( "<li></li>" )
    .data( "item.autocomplete", item )
    .append( "<a>" + item.AccountName + " (" + item.AccountNum + ")" + "</a>" )
    .appendTo( ul );
  };
});

The important things to note here:

  • Select Function: We’re setting the select function to allow us to handle what happens when the user selects an item ourselves. Returning false prevents the default handler from running.
  • Focus function: As above, we’re handling focus ourselves so that we can display the custom data field of our choosing. By default the ‘value’ property would be used.
  • Render Item: We’re overriding this to give us control over how data is presented in the drop down list that is shown whilst searching. Again this allows us to display custom data fields, rather than the default ‘value’ field that the auto-complete field expects.

You should end up with something like this:

Summary

So there we have it, a simple example of how to hook up Jquery auto-suggest to an ASP .Net MVC controller with custom data. Enjoy!

Dependancy Injection And Ninject

I’m going to look at another useful item to have in your developer toolbox today: Dependancy Injection.

What Is It And Why Should I Care?

Dependancy Injection is a pretty large topic in itself, but what it boils down to is breaking down tightly coupled classes by using interfaces to provide a level of indirection. There is a good example of this on the Ninject Wiki.

class Samurai {
  readonly Sword _sword;
  public Samurai() {
    _sword = new Sword();
  }
  public void Attack(string target) {
    _sword.Hit(target);
  }
}

If we wanted to break the tight coupling between a Samurai and his sword, to allow the samurai to attack with any weapon, we could do the following:

class Samurai {
  private IWeapon _weapon;
  public Samurai(IWeapon weapon) {
    _weapon = weapon;
  }
  public void Attack(string target) {
    _weapon.Hit(target);
  }
}

This allows us to provide the samurai with any weapon that implements the IWeapon interface, removing the tight coupling between the samurai and his weapon. This is the essence of Dependancy Injection.

My framework of choice is Ninject, so let’s look at how to setup a project to use it.

Setting Up Ninject

There are two things we need to do to setup Ninject, the first is to setup a module that will register all our dependancies:

class ExampleModule : StandardModule
{
    public override void Load()
    {
        Bind<ISamurai>().To<Samurai>();
        Bind<IWeapon>().To<Sword>();
    }
}

Next thing to do is create a kernel; this acts as a repository that will let us request instances of the types we registered.

IKernel kernel = new StandardKernel();

Example Usage

Now that the setup has been completed, we can access the object repository using the kernel:

Samurai s = kernel.Get<ISamurai>();

As the kernel uses generics, we can get a strongly typed result. Now, assuming we used the second class definition of Samurai which has a constructor with an IWeapon argument, we’ll receive an instance of a Samurai with a sword weapon. When creating new object instances, Ninject will check what parameters an object’s constructor requires, create new instances of each and inject them automatically. This is how we ended up with a Samurai with a sword, as our config specified that when an IWeapon object is required, a Sword should be provided.

This can become massively useful in a number of ways. For example. say you want to add logging to a class, simply include an ILogger in the constructor, and start logging. You don’t need to worry about setting up the logger as that’s conveniently handled elsewhere. Need to change the method of logging? Change it in the one place and feel a smug satisfaction that you don’t need to check through all your code for that one place where you dealt with it differently.

Activation Behaviours

“But what if I don’t want a new instance every time?” I hear you ask. Ninject provides some flexibility in how new objects are created through Activation Behaviours.

For example, if we only wanted a single instance of a given class, we could configure it like so:

Bind<ISession>().To<Session>().Using<SingletonBehavior>();

Or say we’re writing a multi-threaded application, and only wanted one instance of a particular class per thread:

Bind<ISession>().To<Session>().Using<OnePerThreadBehavior>();

The other supported behaviours are TransientBehaviour, which is the default and creates a new object every time it is requested; and OnePerRequestBehavior, which will create an object instance once for each web request.

Summary

So hopefully you now have an idea of what Dependancy Injection is, what it can do for you, and how to get a simple application architecture up and running with Ninject.

Ninject provides a lot more flexibility than has been presented here, allowing for much more complex activation scenarios: an entire object graph can be created with a single call to IKernel.Get. When you have an object graph several levels deep, this can really help in ensuring things are created in a consistent manner.

Logging With Log4Net

Jumping back to a bit of .Net development this week.

As techniques go, logging is one of the simplest and most useful in a developer’s toolbox. Once your code is out and running in the wild, it becomes a lot harder to track down issues without being able to jump into the debugger. Logging to the rescue!

There are a number of logger implementations for the .Net Framework, including nLog, Microsoft’s Enterprise Library, and my personal choice, log4net.

log4net is a very flexible logging library that provides the ability to log to a number of different outputs, which can be changed easily through configuration files, even at run time.

Setting Up

In your AssemblyInfo.cs add the following to have the config picked up:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]

Specifying the watch option will cause log4net to monitor the configuration file for changes. This is fantastically useful, allowing you to change the logging level dynamically without needing to restart your application.

Speaking of configuration, add a file named log4net.config to the root of your project:

<log4net debug="false">
  <!-- Define some output appenders -->
  <appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net" >
    <param name="File" value="logs/log.txt" />
    <param name="AppendToFile" value="true" />
    <param name="RollingStyle" value="Size" />
    <param name="MaximumFileSize" value="250KB" />
    <param name="StaticLogFileName" value="true" />
    <param name="MaxSizeRollBackups" value="10" />

    <layout type="log4net.Layout.PatternLayout,log4net">
      <param name="ConversionPattern"
        value="%d{dd/MM/yy HH:mm:ss} %-5p %m%n" />
    </layout>
  </appender>

  <!-- Setup the root category, add the appenders and set the default priority -->
  <root>
    <priority value="INFO" />
    <appender-ref ref="rollingFile" />
  </root>
</log4net>

This specifies a logger that will output to a file in the logs directory, along with a default logger that will log anything above an info message.

Start Logging

Once that’s done, start logging!

ILog logger = log4net.LogManager.GetLogger("Logger");
logger.Info("Testing logging");

Bonus: NHibernate

NHibernate has built in support for log4net which can be really helpful when trying to debug issues.

To enable logging for NHibernate, all you need to do is add the following loggers to the log4net.config file:

<logger name="NHibernate" additivity="false">
    <level value="INFO"/>
    <appender-ref ref="rollingFile" />
  </logger>

  <logger name="NHibernate.SQL" additivity="false">
    <level value="INFO"/>
    <appender-ref ref="rollingFile" />
  </logger>

Alter the level value to change how much detail you get. Info will get you a lot of detail on queries being run, whilst Warn or Error will limit output to just those messages that are fired off when things are going wrong.

*Update*

I’ve just been bashing my head against the wall trying to get some logging out of NHibernate, whilst not actually logging anything else.

It seems that because I wasn’t instantiating a logger anywhere in code, this was preventing anything being logged by NHibernate.

All I ended up doing was placing the following in my MVCApplication class:

private static ILog logger = log4net.LogManager.GetLogger("default");

*Another Update*

Just for my own sanity so that I don’t forget again, you will also need to give write access to the log folder for the user that will be writing there. In the case of ASP .Net MVC, this will be the user setup in the app pool, which is usually something like “IIS AppPool\DefaultAppPool” or “IIS AppPool\ASP.Net v4.0”.