Ninject with MVC and ValidationAttributes

Posted by Jack Altiere on May 4th, 2010

I was recently working on an MVC application and I ran into a problem.  I was creating a ValidationAttribute and I needed to have access to my repository in this attribute.  The use case is that I want to add a release of an application, and I want to make sure that the ID being passed in is actually a valid application.  My first pass at this was to try and use property injection, like this:

public class ApplicationIDValidAttribute : ValidationAttribute
{
    [Inject]
    public IRepository<Application> AppRepo { set; private get; }

    public override bool IsValid(object value)
    {
        // Don't force required here, they can use the required attribute.
        if (value == null)
        {
            return true;
        }

        int appID;
        if (!Int32.TryParse(value.ToString(), out appID))
        {
            return false;
        }

        // This did not work, AppRepo was not injected
        var app = AppRepo.LoadApplicationById(appID);

        return (app != null);
    }
}

The problem here is that because of the way attributes are instantiated, this injection method does not work.  In the above code sample, when this gets executed my AppRepo is null.

Service Locator


The solution to my problem ended up being the use of a service locator to handle my injection.  I could have went with the Common Service Locator library, but that isn’t exactly what I want.  I already know what DI container I want to use, so completely abstracting that layer away isn’t what I need.  I ended up creating a library to handle the wiring up of Ninject, and to basically act as a wrapper to access the Ninject kernel. 

public static class Container
{
    private static IKernel _kernel;

    public static void Initialize(IKernel kernel)
    {
        _kernel = kernel;
    }

    public static T Get<T>()
    {
        return _kernel.Get<T>();
    }

    public static object Get(Type type)
    {
        return _kernel.Get(type);
    }
}


Then, I could wire up my service locator in my global.asax file, like this:

// This is in my global.asax.cs file
// Required because I inherited from NinjectHttpApplication
protected override IKernel CreateKernel()
{
    var kernel =  new StandardKernel(new DataModule());

    // Gives my wrapper class access to the kernel instance
    Container.Initialize(kernel);

    return kernel;
}

// This is my data module for reference.
public class DataModule : NinjectModule
{
    public override void Load()
    {
        Bind(typeof (IRepository<>)).To(typeof (Repository<>));
    }
}

Then, to close the loop, I can wire up my attribute like this:

public class ApplicationIDValidAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        // Don't force required here, they can use the required attribute.
        if (value == null)
        {
            return true;
        }

        int appID;
        if (!Int32.TryParse(value.ToString(), out appID))
        {
            return false;
        }

        var repo = Container.Get<IRepository<Application>>();
        var app = repo.LoadApplicationById(appID);

        return (app != null);
    }
}

Don’t Abuse It


I try to only use my service locator container when I have to.  I use standard property or constructor injection whenever possible, but this does provide a nice way to be able to inject into my ValidationAttribute classes.

kick it on DotNetKicks.com

Learning Dependency Injection

Posted by Jack Altiere on August 29th, 2007

I’ve been hearing about dependency injection for quite a while now, and I figured it was about time for me to figure out what all the hype was about.

I  decided I probably needed some more background on the subject before I got started with it, so I watched a video by Bob Lee that served as an introduction to the dependency injection framework for Java put together by Google called Guice.

After seeing that video, and reading an interesting article and discussion about the topic, I decided it was time for me to jump right in.  I’m going to use a new DI framework for .NET called Ninject to figure out how dependency injection works, and how it could be useful for me.

The only good way to get started was to download it and try it, so it was off to http://svn.ninject.org/trunk to download the latest build from the subversion repository.  Now that I have the library, I needed to come up with some sort of small project that I could create to test the dependency injection pattern.  I decided to create a time tracking system where I could log hours on projects, keep track of clients, etc.

The first thing I have to do is come up with the basic architecture for my  project, and then figure out how to best use dependency injection to accomplish my goals.  After thinking about the things I wanted to do with my time tracking application, I fired up Visual Studio and started laying out the architecture.    From a solution standpoint, I broke up the application into several projects.  The first one was a class library that I called TimeTracker.Model.  This library is going to hold the definition for all of my entities, and the class diagram looks like this: (for now)

TimeTracker.Model Class Diagram

The next project in the solution is a collection of all of the services and / or interfaces that I am going to need.  This is where I begin to see where dependency injection is going to start to pay off.  My thought right now is that I want to have some sort of service that stores this information in a database, but I don’t really want to write that part now.  I’m going to write a mock service that will be derived from the same interface to allow me to work on the UI and repository without creating the database tables yet.  I can just inject the repository model that I want and let Ninject figure out what I’m trying to do.  At this point I have 2 services that both implent my IRepository interface, as shown here:

serviceDiagram

I haven’t implemented anything yet on the DBRepository, I’m going to use the MockRepository to get the UI figured out without having to worry about writing stored procedures, creating and updating database tables, etc. 

The third project I have in my solution is called TimeTracker.Shell.  This is where the Ninject kernel is going to be wired up, and where I define my injection bindings.  I also have a project called TimeTracker.UI which will contain all of my forms, user controls, etc.  I could have probably combined these into one project, but I decided to split them up.   This is where I start getting into dependency injection and the Ninject framework.  The first thing I had to do was create a module where I could define my bindings.  When I set up my module, I extended the StandardModule type, as shown here.

   1: namespace Jaltiere.TimeTracker.Shell
   2: {
   3:    public class ServiceModule : StandardModule
   4:    {
   5:       public override void Load()
   6:       {
   7:          Bind<IRepository>().To<MockRepository>();
   8:       }
   9:    }
  10: }

I am trying to keep all of my NInject modules, etc in my shell.  That way it is easier to make changes later should my requirements change.  The binding above is binding my repository to my mock repository.  This binding is what I am going to change after I add my database repository.  After I have my binding set up, I need to create a form in my UI.  This will be the form that starts up with the application.  When I set up my form, the important thing here is to create a constructor that takes an IRepository type, and tag it with the NInject attribute [Inject], which is defined in the Ninject.Core .dll.  To keep the designer happy, I also kept the default constructor too.  My form looks like this:

   1: namespace Jaltiere.TimeTracker.UI
   2: {
   3:    public partial class MainForm : Form
   4:    {
   5:       private IRepository _repository;
   6:  
   7:       public MainForm()
   8:       {
   9:          InitializeComponent();
  10:       }
  11:       
  12:       [Inject]
  13:       public MainForm(IRepository repository) : this()
  14:       {
  15:          _repository = repository;
  16:       }
  17:    }
  18: }

Now I can use the _repository variable in my form, and it won’t matter if it’s using a mock service, a database service, or whatever.  The UI code will not have to change at all.  I understand that Ninject will also recursively solve dependencies, which is sweet.  This means that if my repository had dependencies, they would be injected automatically for me here.

We’re missing one part now, I need the shell to start up my main form, and I also need to link up the module I created with the Ninject kernel.  This happens in Main() function located in the shell project.  My main function now looks like this:

   1: namespace Jaltiere.TimeTracker.Shell
   2: {
   3:    static class Program
   4:    {
   5:       [STAThread]
   6:       static void Main()
   7:       {
   8:          // Set up Ninject for dependency injection.
   9:          IKernel kernel = new StandardKernel(new ServiceModule());
  10:  
  11:          Application.EnableVisualStyles();
  12:          Application.SetCompatibleTextRenderingDefault(false);
  13:          
  14:          // Get the main form through the kernel so it gets the proper injections.
  15:          Application.Run(kernel.Get<MainForm>());
  16:       }
  17:    }
  18: }

At this point, I can use the _repository variable defined in my form, and Ninject will give me a MockRepository implementation, since that is the binding I set up.   This has been a very rudimentary look at dependency injection, specifically the Ninject framework.  I’m beginning to see the value that dependency injection provides, and I will continue to explore these ideas as this project continues.  Stay tuned!  I’ll post another article when I get further along. 

kick it on DotNetKicks.com

Downloads

Twitter Updates

    Top Commentators

    • No commentators.

    Copyright © 2007 Jack Altiere. All rights reserved.