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();
}
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();
}
}

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.

Ninject, MVC3 And Web Requests

Continuing to play with Ninject and MVC3, I wanted to explore further how Ninject can help manage objects over the life of a web request. One of the great things about Ninject is that it allows you to easily change the scope in which objects live through use of Activation Behaviours.

Behave Yourself!

Using Ninject, you can control when new instances of objects are created with Activation Behaviours (although this documentation appears to be out of date at the time of writing).

To set the activation behaviour of a binding, you append a call like so:
Bind().To().InTransientScope();

Ninject has the following scopes built in:

  • TransientScope: A new instance is created for each request.
  • SingletonScope: Only a single instance of an object is created, and the same instance is returned every time.
  • ThreadScope: A new instance is created for each thread.
  • RequestScope: A new instance is created for each web request.

RequestScope and MVC

What I was interested in was whether the RequestScope would create a new instance of something at the start of a web request, and then immediately clean said object up at the end of the request, so that objects wouldn't be kept around longer than they were needed.

A simple test ensued:
public class MvcApplication : NinjectHttpApplication
{
private static ILog logger = log4net.LogManager.GetLogger("default");

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

}

protected override Ninject.IKernel CreateKernel()
{
return new StandardKernel(new MyModule());
}

protected override void OnApplicationStarted()
{
base.OnApplicationStarted();

AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}

public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind().To().InRequestScope();
}
}

public interface ITestInterface { }

public class TestClass : ITestInterface, IDisposable
{
public void Dispose()
{
System.Console.WriteLine("Disposing");
}
}

public class HomeController : Controller
{
ITestInterface test;
public HomeController(ITestInterface test)
{
this.test = test;
}

public ActionResult Index()
{
return View();
}
}

All I did here was setup a controller that would take an instance of a disposable test class. We know it gets created and passed to the controller, so all I wanted to see was that it was disposed at the end of the request. I did this by setting a breakpoint in the dispose method of the class and debugging through Visual Studio.

If you run up the project, you'll see that the breakpoint gets hit after the request has been served, nice and promptly; exactly what I was hoping for.

Making NHibernate Behave

The recommended way or using NHibernate with MVC is to have a single session created per request. That is each time a client makes a request for a page, a new session is opened and kept open until the request is complete and data is returned to the client.

Sounds a little like the RequestBehaviour activation type fits perfectly here doesn't it?

To test this, we need to setup NHibernate and create a simple user class and repository. So to start, here's how I like to get my session factory:
namespace DITest
{
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)).
ExposeConfiguration(c => c.Properties.Add("hbm2ddl.keywords", "none")).
Mappings(m => m.FluentMappings.AddFromAssemblyOf()).
BuildSessionFactory();
}

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

return sessionFactory.OpenSession();
}
}
}

And this is registered with Ninject like so:
Bind().ToMethod(x => SessionFactoryProvider.OpenSession()).InRequestScope();

Next, a simple user class, mapping (I'm using FluentNhibernate here to do the mapping) and repository (all in one place for brevity):
namespace DITest
{
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
{
public UserMap()
{
Id(c => c.Id);
Map(c => c.Name);
Map(c => c.Age);
}
}

public class UserRepository
{
ISession session;
private IQueryable Users
{
get { return session.Query(); }
}

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

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

Finally, updated the controller to pull some information from the database:
public class HomeController : Controller
{
UserRepository repo;
public HomeController(UserRepository userRepo)
{
repo = userRepo;
}

public ActionResult Index()
{
ViewBag.Users = repo.GetUsers();
return View();
}
}

To verify this was all working correctly and the session is being closed properly, I setup logging to log debug information, which churns out tons of useful information:






Then after running up the page and doing a request, we can look at the generated log and see what's been happening:
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] opened session at timestamp: 634462405708, for session factory: [/b9e13234ae244e18b7f2ce1923c58e48]
14/07/11 12:42:50 DEBUG Begin (Unspecified)
14/07/11 12:42:50 DEBUG Obtaining IDbConnection from Driver
...//edited for brevity
14/07/11 12:42:50 DEBUG IDbTransaction disposed.
14/07/11 12:42:50 DEBUG transaction completion
14/07/11 12:42:50 DEBUG aggressively releasing database connection
14/07/11 12:42:50 DEBUG Closing connection
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] running ISession.Dispose()
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] executing real Dispose(True)
14/07/11 12:42:50 DEBUG closing session
14/07/11 12:42:50 DEBUG running BatcherImpl.Dispose(true)

I've cut out a lot of the logging that just details queries are happening so that we can see what we care about; that the session is being closed properly after the requests have happened, and not before!

Summary

We looked at the various types of activation behaviour that Ninject supports, delved deeper into RequestBehaviour and verified that it is in fact doing what it says on the tin, and then saw how this is useful when working with MVC and NHibernate.

So now we have an NHibernate session that will last for the duration of a request. What would be really useful now is some concept of a unit of work, to allow multiple Nhibernate requests to be batched into a single transaction. Stay tuned!

Ninject And ASP .Net MVC3

I've mentioned Ninject before, it's an excellent dependancy injection framework that lets you keep your code loosely coupled.

I've also mentioned that I've been working with the MVC Framework quite a lot of late, and what's neat is that hooks are provided that make it easy to use your own dependancy injection framework. To that end, this post will be looking at how Ninject can be integrated with MVC3, and why that's awesome!

I'll be working with a clean MVC3 project created in Visual Studio 2010. There are a couple of ways of integrating Ninject; using the IDependancyResolver interface, or inheriting from NinjectHttpApplication.

Option 1: IDependancyResolver

All we need to do here is implement IDependancyResolver and then register an instance of it on application startup.

So a simple implementation for Ninject will look something like this:
using System;
using System.Web.Mvc;
using System.Collections.Generic;
using Ninject;
using Ninject.Modules;

public class NinjectResolver : IDependencyResolver
{
IKernel kernel;

public NinjectResolver(INinjectModule[] modules)
{
kernel = new StandardKernel(modules);
}

public object GetService(Type serviceType)
{
return kernel.Get(serviceType);
}

public IEnumerable GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
}

And we register this in Application_Start with a simple call like so:
var resolver = new NinjectResolver(new MyModule());
DependencyResolver.SetResolver(resolver);

MVC3 will then use this object when trying to instantiate an instance of a class, but will fall back to it's built in methods for locating objects if this fails. What this means in practice is that you don't need to worry about registering all of the default objects MVC3 uses such as the controller factory, leaving you free to just deal with the stuff you care about.

Option 2: NinjectHttpApplication

The second option is to make use of Ninject's MVC3 extension which can be found here.

In this case, all we need to do is change our MvcApplication class (found in Global.asax) to inherit from NinjectHttpApplication instead of MvcApplication, and then implement CreateKernel to register the modules we've created.

public class MvcApplication : NinjectHttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

}

protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}

public override IKernel CreateKernel()
{
return new StandardKernel(new MyModule());
}
}

And that's it; now Ninject will be used to resolve any dependencies that are requested when the object model is being built.

Which Approach?

But which of the two approaches should you use? It doesn't matter hugely, the first option allows for a very quick integration, you could even register a dependency resolver in a much more concise fashion making use of lambdas like so:
var kernel = new StandardKernel(modules);
DependencyResolver.SetResolver(
t => {
try { return kernel.Get(t); }
catch { return null; }
},
t => kernel.GetAll(t)
);

However, using Ninject's MVC3 extension is marginally more self contained, so I tend to prefer making use of NinjectHttpApplication instead. Note that Ninject will still find the right controllers without registering them, so there is no need to register all your controllers unless you want to add additional configuration to them.

If you think you're likely to want to change your DI framework, then it would make more sense to make use of the IDependancyResolver interface so that you can drop in a quick replacement, although personally I think that scenario is somewhat unlikely.

Now you're loosely coupled

So that's a couple of simple ways to integrate Ninject with MVC3; not too hard to achieve and provides a lot of power and flexibility.

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().To();
Bind().To();
}
}

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();

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().To().Using();

Or say we're writing a multi-threaded application, and only wanted one instance of a particular class per thread:
Bind().To().Using();

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.