Contents tagged with MVC

  • Live Kitten Juggling with ASP.NET MVC

    Are you as excited as I am about ASP.NET MVC but want to know more. Or have you been struggling all your life in Web Forms Hell and want to make the leap to MVC and don’t know where to start or who to turn to?

    kitties_small

    Jon Galloway and Christopher Harrison are presenting a fast-paced live virtual session (no travel required, except to get from the couch to the computer which I know is a task but we can do it) that walks you through getting introduced to MVC, Visual Studio, Bootstrap, Controllers, Views, and bears oh my!

    It’s a free-as-in-beer all-day session. If you know some C#, a little HTML, and some JavaScript and want to amp up your game then I encourage you to drop by. The free Microsoft Virtual Academy event runs from 9:00am – 5:00pm PDT on June 23, 2014. Check out this page for more details where you can also register for the event.

    See you there!

  • Convention over Configuration with MVC and Autofac

    One of the key things to wrap your head around when doing good software development using frameworks like ASP.NET MVC is the idea of convention over configuration (or coding by convention).

    The idea is that rather than messing around with configuration files about where to find things, how to register IoC containers, etc. that we used to do, you follow a convention, a way of doing things. The example normally expressed is a class in your model called “Sale” and a database named “Sales”. If you don’t do anything that’s how the system will work but if you decide to change the name of the database to “Products_Sold” then you need some kind of configuration to tell the system how to find the backend database. Otherwise it can naturally find it based on the naming strategy of your domain.

    MVC does this by default. When you create a controller named “Home” the class is HomeController and the views of the HomeController are found in /Views/Home for your project. When dealing with IoC containers there’s the task of registering your types to resolve correct. So let’s take a step back and take a look at a project with several repositories in it (a repository here being some kind of abstraction over your data store).

    Here we have under our Models: Customer, Invoice, and Product with their respective classes, repositories, and interfaces:

    image

    This might be how your project is typically setup. I want to inject the dependencies on my repositories into my controller (via my IoC system) like this:

       1:  public class HomeController : Controller 
       2:  { 
       3:      private readonly ICustomerRepository _customerRepository; 
       4:      private readonly IInvoiceRepository _invoiceRepository; 
       5:      private readonly IProductRepository _productRepository;
       6:   
       7:      public HomeController(
       8:  ICustomerRepository customerRepository,
       9:  IInvoiceRepository invoiceRepository, 
      10:  IProductRepository productRepository) 
      11:      { 
      12:          _customerRepository = customerRepository; 
      13:          _invoiceRepository = invoiceRepository; 
      14:          _productRepository = productRepository; 
      15:      }
      16:   
      17:      // 
      18:      // GET: /Home/ 
      19:      public ActionResult Index() 
      20:      { 
      21:          return View(); 
      22:      } 
      23:  }

    Then somewhere in my controller I’ll use the various repositories to fetch information and present it to the user (or write back values gathered from the user). How do my IoC know how to resolve an ICustomerRepository object?

    Here’s how I have my IoC engine setup for this sample using Autofac. You can use any IoC engine you want but I find Autofac works well with MVC. First in Global.asax.cs I just follow the same pattern that the default projects setup and add a new static class called ContainerConfig.RegisterContainer()

       1:  public class MvcApplication : System.Web.HttpApplication 
       2:  { 
       3:      protected void Application_Start() 
       4:      { 
       5:          AreaRegistration.RegisterAllAreas();
       6:   
       7:          WebApiConfig.Register(GlobalConfiguration.Configuration); 
       8:          FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
       9:          RouteConfig.RegisterRoutes(RouteTable.Routes); 
      10:          BundleConfig.RegisterBundles(BundleTable.Bundles); 
      11:          ContainerConfig.RegisterContainer(); 
      12:      } 
      13:  }

    Next is setting up Autofac. First add the Autofac MVC4 Integration package either through the NuGet UI or the Package Manager Console:

    PM> Install-Package Autofac.Mvc4

    Next here’s my new ContainerConfig class I created which will register all the types I need:

       1:  public class ContainerConfig 
       2:  { 
       3:      public static void RegisterContainer() 
       4:      { 
       5:          var builder = new ContainerBuilder(); 
       6:          builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
       7:          builder.RegisterType<CustomerRepository>().As<ICustomerRepository>(); 
       8:          builder.RegisterType<InvoiceRepository>().As<IInvoiceRepository>(); 
       9:          builder.RegisterType<ProductRepository>().As<IProductRepository>(); 
      10:          var container = builder.Build(); 
      11:          DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
      12:      }
      13:   
      14:  }

    What’s going on here:

    Line 5 Create a new ContainerBuilder
    Line 6 Register all the controllers using the assembly object
    Line 7-9 Register each repository
    Line 10 Build the container
    Line 11 Set the default resolver to use Autofac

    Pretty straight forward but here are the issues with this approach:

    1. I have to keep going back to my ContainerConfig class adding new repositories as the system evolves. This means not only do I have to add the classes/interfaces to my system, I also have to remember to do this configuration step. New developers on the project might not remember this and the system will blow up when it can’t figure out how to resolve INewRepository
    2. I have to pull in a new namespace (assuming I follow the practice of namespace = folder structure) into the ContainerConfig class and whatever controller I add the new repository to.
    3. Repositories are scattered all over my solution (and in a big solution this can get a little ugly)

    A little messy. We can do better with convention over configuration.

    First step is to move all of your repositories into a new folder called Repositories. With ReSharper you can just use F6 to do this and it’ll automatically move and fix the namespaces for you, otherwise use whatever add-in your want or move it manually. This includes both the classes and interfaces. Here’s what our solution looks like after the move:

    image

    Pretty simple here but how does this affect our code? Really minimal. In the controller(s) that you’re injecting the repository into, you just have to remove all the old namespaces and replace it with one (whatever namespace your repositories live in).

    The other change is how you register your ContainerConfig. Here’s the updated version:

       1:  public class ContainerConfig 
       2:  { 
       3:      public static void RegisterContainer() 
       4:      { 
       5:          var builder = new ContainerBuilder(); 
       6:          builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
       7:          builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
       8:              .Where(x => x.Namespace.EndsWith(".Repositories"))
       9:              .AsImplementedInterfaces(); 
      10:          var container = builder.Build(); 
      11:          DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
      12:      } 
      13:  }

    Note that a) we only have one line to register all the repositories now and b) the namespace dependency we had in our file is now gone.

    The call to RegisterAssemblyTypes above using the convention of looking for any class/interface in a namespace that ends with “.Repositories” and then simply registers them all.

    So for the new developer on the project the instructions to them are to just create new repository classes and interfaces in the Repositories folder. That’s it. No configuration, no mess.

    Hope that helps!

  • Getting Started with ASP.NET MVC 3, Logging, and Depency Injection

    I started a new ASP.NET MVC project recently and wanted to give you a little insight on kicking off new projects. There’s some setup time you want to spend setting up your solution and getting the plumbing in order before you dive into writing unit tests and building out your site.

    For a full on, blow my mind, ultimate guide you *have* to go watch Rob Conery and his 90 minute walkthrough of setting up his MVC projects. I’ve watched this video a few times and Rob is awesome and knows his stuff. The tips he gives are gold. You can also check out the MVC 3 Starter Kit on CodePlex which is based on his MVC 2 Starter code but I found it was lacking a few features. In any case, go watch his video for the full meal deal either here on YouTube or here on TekPub. This post is just a mere shadow of his work but updates the use of Ninject with MVC 3.

    Okay, so we’re going to be doing some simple plumbing to get this going. We’ll put together the Hello World MVC 3 app, add in a logging system, and plumb in dependency injection in just a few minutes.

    You’ll need Visual Studio 2010 with MVC 3 and NuGet installed. You can get MVC 3 from the main site here. Next install NuGet from here. The MVC 3 framework is obviously needed (Visual Studio 2010 only comes with MVC 2 out of the box) and NuGet is used to install our additional libraries (trust me, if you haven’t used NuGet before it will blow your mind).

    First steps is to build a new MVC 3 app. File > New Project. Then select Visual C# > Web > ASP.NET MVC 3 Application and give it a name.

    image

    Click OK and you’ll see the options dialog for a new MVC 3 Application.

    image

    Pick Internet application as it will work for most everyone (Windows authentication works fine too but for this post it’s just easier to go with Internet). Let’s choose Razor for the view engine (ASPX is so 2011) and use HTML 5 markup (hey, it’s just a demo). We won’t create a unit test project but in a real project you’ll create one (or create a class library separately so you can use other unit testing frameworks).

    We’re creating a project based on the template to give us a controller as we’ll inject our dependency into it later, otherwise we would have to create those. In a real project we might start with an empty template and create our own controllers from scratch (again, demo land, remember?).

    Once you do that you’ll be at the Hello World project of the MVC world.

    image

    Okay, now we’re going to install two NuGet packages, Ninject and NLog. Ninject is an open source dependency injection framework and makes working with external dependencies (like infrastructure and services) a breeze. NLog is a free logging solution for .NET and allows you to write anything to almost any target including files, event logs, web services, mail, forms. You name it, it can write to it. I was using log4net for all my projects but lately I’ve switched over to NLog. It’s super-simple to use and highly flexible. Did I mention it’s available as a NuGet package?

    Right click on the References in your project and choose Manage NuGet Packages…

    image

    Make sure you’re looking at the Online packages (sometimes the dialog will open up to installed packages or updatable ones). Type in “nlog” into the search box and you’ll see the filtered search results. Choose NLog Configuration from the options. If you already had a log configuration file you can just choose NLog to install the logger but since we’re starting from scratch we need a config file to start with. Selecting NLog Configuration and you’ll see it has a dependency on NLog so you can just install the one package which installs a starter config file and then drags along the library with it. Easy.

    image

    Once you’ve installed NLog you can enter “ninject” in the search box. This will bring up a list of packages for the dependency injection library Ninject by Nate Kohari. You’ll want to install the Ninject.MVC3 package by Remo Gloor and Ian Davis. This package will install Ninject itself and the extensions for MVC 3 (along with the bootstrapper for web projects. Ninject requires you to review and accept the license agreement before it will install so go ahead and do that.

    Two packages and all of their dependencies but you’re now only a few minutes (yes, minutes) away from dependency injection heaven and MVC 3.

    The first thing we’re going to do is create an interface that will be our logging system. We have a logger (NLog) but that’s an implementation and while we could scatter NLog statements all over the place, we would be tied directly to that library. If we decided to phase out NLog and replace it with another library (such as how I’ve shifted from log4net to NLog) we would have to go through everywhere in our code and replace the NLog calls with the next best thing.

    This the one of the principles of dependency injection, abstraction, and SOLID. Creating an abstraction of an implementation to code against without tying ourselves to any one system (so to speak). At the end of the day we’ll still be calling into NLog functions but we’ll be doing it through an implementation class via our interface.

    The other key thing about this approach is that we we can mock or stub out the actual implementation of our logger for unit testing. You can really do that (very well) with concrete implementations. Imagine having to start up a database, file system logger, and the Windows Event log service just to unit test some business code.

    In addition to being able to test our code, we can also code to interfaces meaning that we don’t need the actual implementation until it comes time to actually perform the work. For example the project I’m currently working on is going to require to call out to web services and databases. These components are not built yet and won’t be for another month or so. I don’t want to halt the development of my app so I create service interfaces and repositories that will abstract these away from my system, allowing me to build a fully working (and tested) system (which just happens to use hard coded values for now). Later when those services appear I just build an implementation to talk to them and voila, my system is still working exactly the way it does today.

    Okay, enough talk. Here’s the interface for our logging system. I’m borrowing from Rob’s approach by creating a folder called Infrastructure with a subfolder called Logging. In it I’ll create an ILogger interface that will let me write an information message (most logging systems have various levels of logging like Information, Warning, Errors, etc.)

    image

    And here’s my ILogger interface:

       1: namespace MvcStarter.Infrastructure.Logging
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">public interface</span> ILogger</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         <span style="color: #0000ff">void</span> Info(<span style="color: #0000ff">string</span> message);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span> }</pre>
    

    Next we need an implementation. We’ll create one for NLog. This is a simple class that implements ILogger and provides the Info method (along with the setup needed for NLog to work). Here’s the NLogLogger class:

       1: using NLog;
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span>  </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> <span style="color: #0000ff">namespace</span> MvcStarter.Infrastructure.Logging</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> NLogLogger : ILogger</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>         <span style="color: #0000ff">private</span> Logger _logger;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>  </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>         <span style="color: #0000ff">public</span> NLogLogger()</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>         {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>             _logger = LogManager.GetCurrentClassLogger();</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>         }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>  </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Info(<span style="color: #0000ff">string</span> message)</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>         {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span>             _logger.Info(message);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span>         }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19">  19:</span> }</pre>
    

    We create a private variable of type NLog.Logger and create it in our constructor using the LogManager from NLog. Then to write using NLog we just call the Info method on the class, passing it our message.

    There are a lot of other methods we can call and add to our interface so later maybe we’ll extend that but this is enough to get you started.

    One more thing is that the default config file that was installed with the package is just that, blank. You need to tell it at least what target to use and what rules to apply to each target. The entire config file is documented online but you can just uncomment the sample implementation. Make sure to match up the logger rule (Trace in the config file) with your method you’re calling in the implementation. I just changed the minLevel of the NLog config file from Trace to Info to match our code.

    That’s all you need to have logging working but how do we call it? And how does Ninject fit in?

    Back when we installed Ninject it created a file for us. Go back to your project and check out the App_Start folder. Expand it and you’ll see a new file there called NinjectWebCommon.cs

    image

    This sucker is responsible for kickstarting Ninject for you. If you watched Rob’s video or saw some tutorials on the net they talk about changing the base HttpApplication to a Ninject one. That’s one approach but with MVC 3 and the NuGet package this way is much simpler. There’s nothing for you to do except tell Ninject what dependencies you want to deal with and how to resolve them.

    Open up NinjectWebCommon.cs and scroll down to the RegisterServices method. This is where you’ll specify you own interfaces and concrete classes so Ninject can do it’s magic.

    With a single line we’re going to tell Ninject this:

       1: /// <summary>
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> <span style="color: #008000">/// Load your modules or register your services here!</span></pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> <span style="color: #008000">/// &lt;/summary&gt;</span></pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> <span style="color: #008000">/// &lt;param name=&quot;kernel&quot;&gt;The kernel.&lt;/param&gt;</span></pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> RegisterServices(IKernel kernel)</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>     kernel.Bind&lt;ILogger&gt;().To&lt;NLogLogger&gt;().InSingletonScope();</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span> }        </pre>
    

    What are we saying here? Simple. We’re telling Ninject to:

    • Whenever you see the ILogger interface needed (e.g. passed into a constructor of a class)
    • Resolve to the NLogLogger class
    • Make it a singleton (i.e. only do it once and reuse it over and over again)

    We’re making our logger a singleton because we don’t need to start NLog every time we want to log a message. You can also specify other scopes (like by thread or on demand) but for logging a singleton works.

    Oh yeah, that’s it to hook up your dependency injection engine. And logging is ready to go.

    Let’s give it a whirl. Crack open the HomeController class and add a constructor that takes in an ILogger interface then using that interface, write out a message when the Index method is called (i.e. our home page is visited). Here’s the modified HomeController class:

       1: using System.Web.Mvc;
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> <span style="color: #0000ff">using</span> MvcStarter.Infrastructure.Logging;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> <span style="color: #0000ff">namespace</span> MvcStarter.Controllers</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> HomeController : Controller</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>         <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> ILogger _logger;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>         <span style="color: #0000ff">public</span> HomeController(ILogger logger)</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>         {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>             _logger = logger;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>         }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>         <span style="color: #0000ff">public</span> ActionResult Index()</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span>         {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span>             ViewBag.Message = <span style="color: #006080">&quot;Welcome to ASP.NET MVC!&quot;</span>;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span>             _logger.Info(<span style="color: #006080">&quot;Home page visited&quot;</span>);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19">  19:</span>             <span style="color: #0000ff">return</span> View();</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20">  20:</span>         }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum21">  21:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum22">  22:</span>         <span style="color: #0000ff">public</span> ActionResult About()</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum23">  23:</span>         {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum24">  24:</span>             <span style="color: #0000ff">return</span> View();</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum25">  25:</span>         }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum26">  26:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum27">  27:</span> }</pre>
    

    We add an ILogger interface to the constructor. This trigger Ninject to figure out what implementation to grab (our NLogLogger one) and create it for us (or reuse it since we told it we wanted a singleton). Then we use that implementation in our Index() method to log a message.

    Compile and run the app to visit the home page of your app and you’ll see this in your log:

       1: 2012-05-15 19:18:38.8471 INFO Home page visited

    That’s it. You have a logging system you can call anytime (just inject the interface into the class, Ninject will take care of the rest) and your project is setup with dependency injection and you’re ready to go. Now you can just add additional interfaces as you need them.

    The awesome thing here is that a) you can now mock or stub out your logging implementation and test it and b) replace that implementation with some other logger any time and your code will still just work.

    That’s the power of dependency injection.

    As a bonus piece of information, now that you have the dependency injection setup you can use it any time in case you’re in a pinch and don’t need/want to inject the implementation into your class.

    Here’s how you can call the logger from your Application_Start method (found in Global.asax.cs) before any controllers are fired up:

       1: protected void Application_Start()
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     AreaRegistration.RegisterAllAreas();</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     RegisterGlobalFilters(GlobalFilters.Filters);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     RegisterRoutes(RouteTable.Routes);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     DependencyResolver.Current.GetService&lt;ILogger&gt;().Info(<span style="color: #006080">&quot;Application Started&quot;</span>);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span> }</pre>
    

    See that last line? DependencyResolver.Current.GetService will use whatever IoC you have configured and return the implementation of that interface.

    Okay, that’s enough to get started. Again, I encourage you to watch Rob’s *entire* video of setting up a new MVC project. Even though the video is for MVC 2, there are still a lot of idea that hold water in MVC 3 and it’s a great learning too (and free too).

    Enjoy!