Showing posts with label architecture. Show all posts
Showing posts with label architecture. Show all posts

Monday, 6 May 2013

Aspect-Oriented Programming in C# with PostSharp - Logging Aspect Example

I was looking at some code in a class library project with a colleague recently. One thing that stood out was that a lot of methods across the various classes in the library were using a "Logger" class to persist runtime information (things like actual parameters and exception messages). There was a clear pattern in how these methods were structured, they logged the fact that they were called (with parameter information) and then had logic specific to what they were supposed to do. Any exceptions raised by the main logic of the methods were also logged. The "Logger" instance was not being injected into each of these classes, it was a concrete implementation without an interface. In the end, we came to the conclusion that we could improve this code as follows:

  • We could de-couple the logger from all the classes by using dependency injection. This would involve creating an interface for the logger, ensuring the current logging class implements this interface and then rearchitecting the classes that use the logger so that they are IoC friendly. An IoC container such as Ninject could then be used to inject a specific implementation of the logger into the various classes at runtime.
  • Or, we can make use of Aspect-Oriented Programming (AOP)

The latter of these points is the subject of this blog post. AOP is a programming paradigm just like Object-Oriented Programming (OOP). But instead of focusing on classes, objects and methods - AOP focuses more on separating concerns through "aspects". AOP typically deals with concerns that "cross-cut" a codebase. Luckily for us, the most popular example of a cross-cutting concern seems to be logging. As my colleague and I witnessed in the class library project, logging was being applied across a number of classes, therefore tightly coupling the logger with these classes. Furthermore, it was clear that each method that was logging wasn't adhering to the single responsibility principle.

The goal was therefore to seperate these concerns in a clean way. AOP enables this by letting you implement cross-cutting concerns as aspects which are then applied to existing code through aspect weaving. The C# programming language doesn't have any first-class support for AOP as it is primarily an OOP language. But there are libraries that allow you to apply AOP concepts using existing C# language constructs. One such library is PostSharp, which makes it easy to write an aspect and then apply the aspect to existing code. In the example below, we'll make use of PostSharp to write an aspect for logging method call information to the debug output.

PostSharp Logging Aspect Example

The PostSharp library allows you to define aspects as standard C# attributes. You can do this by deriving from one of the aspect classes from the library and override the methods that are of interest to your aspect. In the logging aspect example below, we derive from the PostSharp.Aspects.OnMethodBoundaryAspect class and override the OnEntry, OnExit and OnException methods.

[Serializable]
public class LogAspectAttribute : OnMethodBoundaryAspect
{
    private Guid _methodCallIdentifier;
               
    public override void OnEntry(MethodExecutionArgs args)
    {
        _methodCallIdentifier = Guid.NewGuid();

        Debug.WriteLine("{0} - Entering method {1} with arguments: {2}",
            _methodCallIdentifier,
            args.Method.Name,
            string.Join(", ", args.Arguments));
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        Debug.WriteLine("{0} - Exited method {1}",
            _methodCallIdentifier,
            args.Method.Name);
    }

    public override void OnException(MethodExecutionArgs args)
    {
        Debug.WriteLine("{0} - Method {1} raised exception with message: {2}",
            _methodCallIdentifier,
            args.Method.Name,
            args.Exception.Message);
    }
}

Note that PostSharp contains a number of predefined aspect classes that you can derive from depending on your particular use case. For instance, the class PostSharp.Aspects.MethodInterceptionAspect is particularly useful for implementing security on methods (i.e. you can decide in your aspect whether to allow the intercepted call to proceeed through).

Back to the example above, the OnEntry method is called just before the target method (the method that we'll annotate with this attribute) is called. The OnExit method is called once the target method completes executing and the OnException method is called if the target method raises an exception. Each of these three methods provide useful points for us to do some logging. The MethodExecutionArgs instance passed to each method also contains some useful context information for us to add to the log.

To now use this aspect, it's a simple case of annotating the methods you want to log with the [LogAspect] attribute, as shown below.

[LogAspect]
void SayHelloToWithoutException(string name)
{
    Console.WriteLine("Hello, {0}!", name);
}

[LogAspect]
void SayHelloToWithException(string name)
{
    Console.WriteLine("Hello, {0}!", name);
    throw new Exception("Oops! Something went wrong...");
}

The logging logic is now neatly encapsulated in one location. If we call the two methods above, one after the other, we'll get the debug output:

Saturday, 30 March 2013

Dependency Resolution in ASP.NET MVC3/4 with Ninject

The topic for this post is setting up the Ninject Inversion of Control (IoC) container in your ASP.NET MVC3/4 applications. I'm assuming the reader has familiarity with the following concepts:

  • Programming to an interface (or contract)
  • The IoC programming technique
  • Dependency injection
  • IoC containers

The intention is for this post to serve as a useful reference for ASP.NET MVC developers who want to get an IoC container (specifically Ninject) up and running swiftly with the MVC framework.

When working on a new MVC project, one of my first steps usually involves setting up an IoC container. I've typically used Ninject as my IoC container due to its ease of setup and intuitive fluent API. As of ASP.NET MVC3, there is the option of using the Ninject extension for MVC3 (wrapped up in a NuGet package called Ninject.MVC3). This option is simple to setup and you'll typically have little reason to use another approach. Another option is to write your own implementation of the IDependencyResolver interface. In this scenario, you'll implement this interface (which again is quite simple with Ninject) and then hook your custom resolver into the framework for it to use. In a nutshell, the MVC framework will use your custom IDependencyResolver implementation as a first port of call to resolve any required dependencies.

In this post, we'll go with the former option.

Using the Ninject.MVC3 NuGet Package

As mentioned, the Ninject.MVC3 NuGet package is an easy way to get Ninject up and running in your project. The first step is to get the package installed in your solution. I'm using Visual Studio 2012 so the steps may differ slightly depending on what version of the IDE you're running on. Right click your MVC solution node in Solution Explorer. Select the "Manage NuGet Packages for Solution" option in the context menu.



This will bring up the NuGet package manager dialog. In the top right, you should see a text box with the watermark "Search Online". Type "Ninject" and hit enter. In the middle pane, you'll see the Ninject.MV3 package, select it and click the Install button.



At this point, the NuGet package manager will have done all of the hard work. If you expand the App_Start folder in your solution, you'll find a new file called NinjectWebCommon.cs.



This file contains a static class definition and a number of static methods. The methods that you're interested in are the CreateKernal and the RegisterServices methods. If you have had experience with Ninject in the past, then you'll be at home with what the CreateKernal method is doing. It creates an instance of the StandardKernal (the default implementation of Ninjects IKernal interface). The StandardKernel is the class you'll use to map (or in Ninject terminology "bind") interfaces to the implementations that you want to use. This is done by using the generic methods Bind and To on the kernel object, where you pass your interface and implementation, respectively, as type parameters. You'll notice that the CreateKernal method makes a call to a method named RegisterServices. This is the method where you'll register your bindings with Ninject.

private static void RegisterServices(IKernel kernel)
{
    // Register your ninject bindings here!
}
Now that Ninject is setup in the project, we'll try and inject a dependency through a controller constructor. In this example, imagine you have a simple logging interface, defined as:

public interface ILogService
{
    void Log(string message);
}
We then have an implementation of this interface:

public class DebugLogService : ILogService
{
    public void Log(string message)
    {
        System.Diagnostics.Debug.WriteLine(message);
    }
}
Imagine further that we now wanted various actions in our HomeController to log to the debug output. With dependency injection, one way to inject our DebugLogService implementation into our HomeController would be through the constructor - as follows:

public class HomeController : Controller
{
    private readonly ILogService _logService;

    public HomeController(ILogService logService)
    {
        _logService = logService;
    }

    public ActionResult Index()
    {
        _logService.Log(
            string.Format("Index() called at {0}", 
                DateTime.Now));

        return View();
    }
}
If you're following the steps and you now run your web application, you'll get a runtime exception stating that there was an error activating ILogService. This is good, as it tells you that Ninject tried to create an instance of the HomeController, but failed in doing so because the HomeController has no default constructor. The constructor that it does have, however, has one required parameter (logService) that Ninject has no type bindings for. We'll now go back to the static RegisterServices method in the NinjectWebCommon class and add the binding as shown below:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<ILogService>().To<DebugLogService>();
}
If you now run the application, you'll find that the HomeController is successfully being instantiated with Ninject passing an instance of the DebugLogService class through to the constructor. You can verify this by looking at the output window for the log entry.



And that's it - you'll now follow this pattern for registering your bindings in the RegisterServices method and programming to your interfaces for which you have registered bindings. As all of your bindings are registered in a single location, swapping out your implementations with other implementations is an easy job. We can now easily switch all logging to a file by writing a new FileLogService (that implements ILogService) and then bind this to the ILogService in the RegisterServices method.

Wednesday, 20 February 2013

Implementing the Chain of Responsibility Design Pattern

Earlier this week I made use of the Chain of Responsibility design pattern to solve a fairly straight-forward problem. I've always been careful when trying to apply design patterns, it's easy to get carried away and try to force a design pattern to a problem that doesn't really require it. In this case, I felt it was justified and hopefully you'll think the same!

The Context

I'll give some context to the problem before we go into exactly what the Chain of Responsibility pattern is. I was working on a HTTP service (built on ASP.NET Web API) which had an API controller action that accepted requests for some data stored in a persistent repository. My requirement was to inspect the incoming request object, and depending on certain characteristics of the request, log the request object data to zero or many different output locations. This is to enable reporting on the types of requests that the service receives. The output locations were disparate data stores such as an XML file, Excel file and SQL Server Database. The key point was that to log the request I had to inspect the content of the request, and depending on some criteria, log it to none or certain data stores. Furthermore, certain requests had to be ignored and therefore not logged.

Chain of Responsibility

When I read this requirement I knew immediately there was a design pattern for this type of problem. I had taken an Object-Oriented design pattern course at university around six years ago but couldn't quite remember the name of the pattern. After having a quick look on the GoF website, I eventually found it - Chain of Responsibility (CoR). CoR is a software design pattern that has been classified into the "behavioral" category of patterns - these are patterns that broadly deal with objects interacting with other objects. The idea is that you have multiple handler objects chained together just like a linked list data structure. An incoming request object is passed over to the first handler in the chain, the handler (depending on its "responsibility"), inspects the request and can either:
  1. Handle the request and not pass the request down the chain of handlers
  2. Handle the request but still pass the request down the chain of handlers
  3. Not handle the request and pass the request down the chain to the next handler
Note that before a handler sends the request object down the chain, it is also responsible for checking if it is actually linked to another handler. If a handler isn't linked to another handler, it is the last handler in the chain and therefore consumes the request.

Applying CoR to the Problem

In my case, the incoming data request to the API was my CoR request that required "handling" from a logging perspective. I implemented a separate concrete logging handler class for each of the concrete data stores (XML, Excel and SQL Server). Each logging handler inspected the request and logged the request if it matched the criteria for the handler before passing the request to the next handler. Therefore, in my case, the CoR handler behaviour corresponded to point two above.

The Implementation

Note that I've stripped down the code below (especially for each concrete handler) so that it is easier to see what's going on from a design pattern perspective.

The first step was to write an abstract base handler that defined the behaviour that each of my handlers will support. The HandlerBase class below is generic enough to be reused in any case where you require a CoR implemented. The single type parameter "TRequest" is the type of the object that will go through your chain (can be any .NET type).
public abstract class HandlerBase<TRequest>
{
    public HandlerBase<TRequest> Successor
    { 
        protected get; 
        set; 
    }

    public abstract void HandleRequest(TRequest request);
}
The HandlerBase class has one property, which allows users of a handler to set a successor to this handler (the next handler in the chain) and it has an abstract method that all derived classes will need to implement - HandleRequest. You will see further below how we use the Successor property when setting up our chain, and how each concrete handler (a class that derives from HandlerBase) uses the HandleRequest method on its successor to pass the request down the chain.

Next, I implemented each of my concrete handlers - that is, a handler for logging to an XML document, Excel document and SQL server.
public class LogRequestToXmlHandler : HandlerBase<ApiDataRequest>
{
    public override void HandleRequest(ApiDataRequest request)
    {
        if (request.Foo == Something && request.Bar == SomethingElse)
            // Log request to xml document

        // Pass on the request to the next handler, if any
        if (base.Successor != null)
            base.Successor.HandleRequest(request);
    }
}
Notice how the concrete handler LogRequestToXmlHandler derives from HandlerBase and passes the type of the object that is going through the chain - ApiDataRequest. Also notice that because we're inheriting from an abstract base class containing one abstract method - we're forced by the compiler to override the HandleRequest method. This method accepts one parameter, the request object. It is in this method that you will place any specific handling logic for the request object - I've added some pseudo-code to demonstrate this. The last couple of lines inspect the Successor property (inherited from the base class), if it isn't null - then we call the HandleRequest on it, thus passing our request down the chain. If Successor returns null, then the current handler is the last in the chain and we do nothing - effectively consuming the request. For completeness, the other handlers are below.
public class LogRequestToExcelHandler : HandlerBase<ApiDataRequest>
{
    public override void HandleRequest(ApiDataRequest request)
    {
        if (request.Foo == Something && request.Bar == SomethingElse)
            // Log request to excel document

        if (base.Successor != null)
            base.Successor.HandleRequest(request);
    }
}

public class LogRequestToDbHandler : HandlerBase<ApiDataRequest>
{
    public override void HandleRequest(ApiDataRequest request)
    {
        if (request.Foo == Something && request.Bar == SomethingElse)
            // Log request to database

        if (base.Successor != null)
            base.Successor.HandleRequest(request);
    }
}
Now that we have our handlers, the final step is to setup our chain so that it's ready to handle requests. The code below shows how the handlers are chained together.
HandlerBase<ApiDataRequest> logToXmlHandler
    = new LogRequestToXmlHandler();

HandlerBase<ApiDataRequest> logToExcelHandler
    = new LogRequestToExcelHandler();

HandlerBase<ApiDataRequest> logToDbHandler
    = new LogRequestToDbHandler();

logToXmlHandler.Successor = logToExcelHandler;
logToExcelHandler.Successor = logToDbHandler;
The first step above was to initialise each handler that will be going into the chain. We then use the Successor property to chain the three handlers together. The beauty of using this pattern is that you can chain however many handlers you want and even make the chain configurable so that it is setup at runtime depending on some settings in a config file.

Now, when a new request came through my API, it was a simple case of invoking the HandleRequest method on the first handler in the chain and passing the ApiDataRequest object through as a parameter. This sent the object down the chain, allowing each log handler to inspect it and decide whether to log it to their individual outputs.
logToXmlHandler.HandleRequest(request);
* Update *

One thing that I missed in this post and is worth mentioning is a scenario where you don't want each concrete handler to decide whether to pass the request on down the chain. In this case, the request would go to every handler in the chain regardless. One way to accomplish this is to update the HandlerBase class as follows:
public abstract class HandlerBase<TRequest>
{
    public HandlerBase<TRequest> Successor
    { 
        protected get; 
        set; 
    }

    public void HandleRequest(TRequest request)
    {
        Handle(request);

        if (Successor != null)
            Successor.HandleRequest(request);
    }

    protected abstract void Handle(TRequest request);
}
The updated HandlerBase now implements a public HandleRequest method which first delegates the handling logic to an abstract method (Handle) which will be overridden by a concrete handler. Once a request has been handled, a test is made to check if there is a successor and if there is, then the request is passed on. What this now means is that each concrete handler will implement just one method, Handle, and not need to worry about whether to pass the request on or not - that is done automatically in the HandleRequest method. An example concrete handler is below:
public class LogRequestToXmlHandler : HandlerBase<ApiDataRequest>
{
    protected override void Handle(ApiDataRequest request)
    {
        // Check request and log it, if required
    }
}

Saturday, 16 February 2013

ASP.NET MVC - Methods in Razor Views (via @helper syntax)

Todays post is about a little-known but very useful feature that was added to the Razor view engine since ASP.NET MVC3. The feature that I'm refering to is the @helper syntax which lets you define reusable methods at the view level. Let's dive straight into an example to show off this feature.

Imagine you have a simple Book model in your ASP.NET MVC project:
public class Book
{
    public string Isbn { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
}
You may then have a controller called BookController with one HTTP GET action called Index. This action may read some books from some repository and pass a list of Book objects to the view. For the sake of brevity, I've hard-coded a couple of Book instances in the snippet below:
public class BookController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        var books = new List<Book>();

        books.Add(new Book {
            Isbn = "9780385660075",
            Title = "The Kite Runner",
            Author = "Khaled Hosseini"
        });

        books.Add(new Book {
            Isbn = "9780571219766",
            Title = "Self",
            Author = "Yann Martel"
        });

        return View(books);
    }
}
Initially, your Razor engine-based Index view may look something like:
@using System.Collections.Generic
@using MvcHelperMethods.Models

@model IList<Book>

<h2>Books Index</h2>

@foreach (var book in Model)
{
    <div>
        <span class="bookTitle">@book.Title</span>
        <span class="bookAuthor">by @book.Author</span>
        <span class="bookIsbn">ISBN: @book.Isbn</span>
    </div>
}
Now imagine that you have a new requirement to introduce another view in your application which shows books by individual authors. The requirement states that the books should be displayed exactly how they are on the Index view. In this scenario, you'll need to create another view that accepts a list of Book objects and renders them out. The only difference being that a different controller action would be used which returns books by a specific author. The view code would look very similar. This presents an opportunity to make use of the @helper syntax in Razor.

The @helper syntax lets you define a view-level method that consists of both C# and Razor syntax. This method can be placed in a specific view or outside of a specific view so that it can be reused across multiple views. We'll use the latter option and define an @helper method called RenderBook which accepts a single parameter of type Book and renders the book out using a mixture of Razor and html syntax.

To accomplish this in your ASP.NET MVC solution, ensure you have the App_Code folder. In Visual Studio 2012, you can add this folder by right-clicking your project then going to Add --> Add ASP.NET Folder --> App_Code. In your App_Code folder, you will now create a new MVC Razor View Page (a .cshtml file). Right click the App_Code folder and go to Add -> New Item. Select the option called "MVC View Page (Razor)", name your view page something sensible - like "ViewHelperMethods.cshtml" then click Add. If there is some pre-defined content in the new view, just remove it all. Now you can write your reusable @helper view method called RenderBook in the ViewHelperMethods.cshtml file:

@using MvcHelperMethods.Models

@helper RenderBook(Book book)
{
    <div>
        <span class="bookTitle">@book.Title</span>
        <span class="bookAuthor">by @book.Author</span>
        <span class="bookIsbn">ISBN: @book.Isbn</span>
    </div>
}
As you can see from the syntax, it's quite similar to the syntax of a standard C# method except you don't specify a return type and access modifier, instead, you use the keyword @helper. You can now refactor your original Index view so that it looks like:
@using System.Collections.Generic
@using MvcHelperMethods.Models

@model IList<Book>

<h2>Books Index</h2>

@foreach (var book in Model)
{
    @ViewHelperMethods.RenderBook(book)
}
Notice that we're now calling our reusable RenderBook method. You can now call the same RenderBook method from your other views, in our case, the view that displays books by specific authors. In summary, if you're working on a fairly large ASP.NET MVC application with many views, then this is a very useful feature to ensure your views are more maintainable.

Update: As pointed out by a reader of this post (on Google+), you also have the option to create a partial view for the Book model and reuse that. The example I gave above was quite simplistic and was aimed at introducing the reader to the @helper feature. I believe the advantage that helper methods give is that you can easily pass them additional parameters at the view level and those parameters can then control exactly how the smaller view is rendered out.

Thursday, 22 December 2011

Inversion of Control with Dependency Injection

I recently heard of the Inversion of Control (IoC) software architecture in a video by Scott Allen. After some googling, I came across the blog post below by Joel Abrahamsson - highly recommended for someone new to the topics of IoC and Dependency Injection. I think the whole idea of IoC shows the advantages of programming to an interface rather than an implementation.

Click here for Joel's blog post.