Twitter Feed Popout byInfofru

OverrideThis.com

Adventures in .NET Software Craftsmanship!

Code and Slides on “Intro to Dependency Injection”

I hIIS Express, Razor, and WebMatrix, oh my! ad the opportunity to participate as the speaker at the Washington DC Dot Net User’s group and really enjoyed presenting an “Introduction to Dependency Injection”. I would like to thank Ganesan Muthiah, the leader of DCDNUG community, for inviting me and also for hosting and managing this fast growing new .NET developer community. 

 

The following are links to the materials used in the presentation.

 

Download Slides & Demo Code

 

Happy coding in .NET!!!

Per Method Call Lifecycle Proxy

Don’t ask why! but I had to code this workaround to plug into some legacy code efficiently and I decided to make the most of the opportunity. 

 

I kept constantly hitting a road block when interacting with a third party assembly that talked to some legacy web services.  In a nutshell, everything worked fine as long as I only called one method per instance of the class, needless to say this was terribly annoying so I decided to do something about it and learn some of the basics of Castle.DynamicProxy to build myself a generic proxy object that lets you implement a per method call lifecycle for an object.  Now this is not intended to be a Castle.DynamicProxy tutorial, but I will try to introduce some of the basics that I learned while coding my solution.

 

What is Castle.DynamicProxy?

Is an OSS project that provides you with the functionality to build dynamic proxy instances to inject functionality that addresses common application concerns.  In other words,  you could build proxies to address security, logging, monitoring and many other repetitive tasks that needs to be coded into any system.  It is used by a ton of very successful open source projects such as AutoMapper, NHibernate and Moq to name a few.   It is extremely easy to use as most of its functionality is exposed by a single class the Castle.DynamicProxy.ProxyGenerator which is usually managed as a single instance (singleton) within your application. 

 

Enough! Lets talk code.  The following snippet shows a simple IService interface and its implementation.  The implementation merely writes some information into the console that should gives us a visual clue (a guid) to easily identity the instance of the object that is servicing the request.

 

public interface IService {    
    Guid Id { get; }
    void DoSomething();
}
public class ServiceImpl : IService {

    public ServiceImpl() {
        this.Id = Guid.NewGuid();
    }

    public Guid Id { get; private set; }

    public void DoSomething() {
        Console.WriteLine("INSTANCE GUID: " + this.Id.ToString());
    }
}

 

When we use the functionality of the class, as illustrated in the following snippet, we see the same guid displayed every time the DoSomething method is called.  Now, if you recalled my objective is to implement a way to create a new instance of the object per method call. In other words, I want to see a different guid for a every single method call to an instance of a proxied IService implementation.

 

var service = new ServiceImpl();
for(var i = 0; i < 5 ; i++)
    service.DoSomething();

// Should Output.
// INSTANCE GUID: ef45bb48-2f9e-4c9f-9c44-345f3a1700c0
// INSTANCE GUID: ef45bb48-2f9e-4c9f-9c44-345f3a1700c0
// INSTANCE GUID: ef45bb48-2f9e-4c9f-9c44-345f3a1700c0
// INSTANCE GUID: ef45bb48-2f9e-4c9f-9c44-345f3a1700c0
// INSTANCE GUID: ef45bb48-2f9e-4c9f-9c44-345f3a1700c0

 

The obvious solution is to build a proxy that would allow you to create a new instance to service the request every time a method is called.   We could code a very simple proxy specific for the IService interface that will do the job in not many lines of code, but there is no fun in that.  Plus, it would restrict the solution to be specific to the IService and its implementations.   By using Castle.DynamicProxy we can implement a generic solution that would allow us to inject this functionality into any object regardless of its contract by using a Proxy and an Interceptor.  The following is such interceptor.

 

public class SingleInstancePerCallInterceptor<T> : IInterceptor {
    private Func<T> builder;

    public SingleInstancePerCallInterceptor(Func<T> builder) {
        this.builder = builder;
    }

    #region Implementation of IInterceptor

    public void Intercept(IInvocation invocation) {
        var changeTarget = invocation as IChangeProxyTarget;
        changeTarget.ChangeInvocationTarget(instance);
        invocation.Proceed();
    }

    #endregion
}

 

Now, if you follow the code above the interceptor has a single constructor parameter that is a Func<T> used to build an instance of the class you are going to proxy.   In its intercept method, which as its name states just intercepts the method calls, there is functionality to build an instance of the class and service the request through Castle’s invocation API.  You might want to add additional logic to make the implementation more robust such as validating that the call is for a method not a property but for demo purposes I kept it simple.  Now the following code is a sample usage that produces the desired outcome by using this interceptor on the IService interface and its implementation object.

 

var generator = new Castle.DynamicProxy.ProxyGenerator();
var service = (IService)generator
    .CreateInterfaceProxyWithTargetInterface(
        typeof(IService), 
        new ServiceImpl(),
    	new[] { new SingleInstancePerCallInterceptor<IService>(() => new ServiceImpl()) });
for(var i = 0; i < 5 ; i++)
    service.DoSomething();

// Should Output.
// INSTANCE GUID: eb203315-d932-4f9f-8956-e9af3b2dcdde
// INSTANCE GUID: 19c528c0-3f35-4619-8276-dd5a270d8e72
// INSTANCE GUID: e7d9b66e-d846-4def-acfe-6a614cc75a78
// INSTANCE GUID: c7dc5dba-8440-478c-a692-5bc1cfe3d4c8
// INSTANCE GUID: 21a8cb42-8398-4bbf-9376-cb3c01ef8325

 

From the above snippet the only line that is somewhat confusing is the one where we are instantiating the service, but once you grasp what is doing is actually very simple.  As the method name implies you are creating a proxy object of type IService with a target, which in our scenario is never going to be used,  this allows the interceptor that is targeting the proxy to do the heavy lifting and switch the target of the invocation as needed.

 

Hopefully, this post illustrates some of the very basic yet powerful things that can be done with Castle.DynamicProxy and how it can help you get out of a bind using non-traditional coding techniques.

Lazy Loading Dependencies with StructureMap

Lately I have been working with an existing custom .NET Library designed to register and execute tasks triggered by events, sort of like a local Event Bus.  The Library was built in house and is used successfully in many applications but it lacks integration with Dependency Injection or Common Service Locator which makes it hard to implement in a solution where separation of concerns are enforced strictly. 

 

To highlight the issue, look at the following snippet, it is a sample of the exposed API for registering tasks associated to an event. 

 

public interface IEventTaskRegister {
    void RegisterFor<T>(ITask action) where T : IEvent;
}
// Sample use scenario.
RegisterFor<OnSomeEvent>(new SomeTask()); 

 

At first glance, there is nothing wrong with the previous code but if you look more carefully you will notice that we are passing a concrete instance of a type.  Now, my preference would be to pass just a type and have the event task library instantiate the type and its dependencies using some form of service location, but modifying the event task library is not an option for us at this time.   One possible solution is to simply use Service Location when we are registering our associated events, as you can see in the following snippet.

 

RegisterFor<OnSomeEvent>(new SomeTask(ObjectFactory.GetInstance<IRepository>()));
// Or Even Less Code.
RegisterFor<OnSomeEvent>(ObjectFactory.GetInstance<SomeTask>());

 

Luckily in the current project all tasks are registered during startup so there isn’t much wrong with muddying the registration code with service location.  But, at this point we have unknowingly created another issue, since the execution of the registration code happens once during system startup the tasks and its dependencies will be unique throughout the execution of the application.  This is a huge problem for us as our current implementation of the IRepository behaves differently depending on context information provided during instantiation, see snippet. 

 

// Repository.
public interface IRepository {
    void DoSomething();
}
public class RepositoryImpl : ITask {
    private readonly IContext context;
    public RepositoryImpl(IContext context) {
        this.context = context;
    }
    public void DoSomething() {
        // Does something that varies
        // depending on the context
        // passed in during instatiation.
    }
}
// SomeTaks
public interface ITask {
    void Execute(); 
}
public class SomeTask : ITask {
    private readonly IRepository repository;
    public SomeTask(IRepository repository) {
        this.repository = repository;
    }
    public void Execute() {
        // Do Something w/Repository.
    }
}

 

One possible solution, is to modify the way we write our implementation of ITask to allow for lazy instantiation of its dependencies but still take of advantage of Dependency Injection an Inversion Of Control.  The following snippet highlights the solution the key is to inject a Func<IRepository> not an IRepository, that way the consumer is actually the one who will be instantiating the dependency on demand.

 

// SomeTaks
public interface ITask {
    void Execute(); 
}
public class SomeTask : ITask {
    private readonly Func<IRepository> repositoryBuilder;
    public SomeTask(Func<IRepository> repositoryBuilder) {
        this.repositoryBuilder = repositoryBuilder;
    }
    public void Execute() {
        var repository = this.repositoryBuilder();
        // Do Something w/Repository.
    }
}
Now the cool part about this solution, is that we don’t need to modify the way we are currently registering our dependencies in StructureMap, all our registries work as expected.

Presenting at MVCConf

I am excited to announce that I will be participating as a presenter at MVCConf.  MVC Conference (MVCConf) is a free virtual conference focused on one thing only, writing awesome application on top of the ASP.NET MVC applications, for more information go to http://www.mvcconf.com

 

I will be doing a presentation on MVC Extensiblity focused on plugging functionality onto your MVC application to enforce separation of concerns therefore enhancing testability. The following are the preliminary details:

 

MVC2 Extensibility

Learn the basic extensibility points of the ASP.NET MVC Framework by refactoring an existing code base and making changes that will make your application less fragile and easier to test.  The main focus will be how to leverage dependency injection, routes, action filters,  model binders, etc. to build a better all-around application.

 

Hope to see you online on the 22h of July!

MVC2 Validation and Testing – Refactored

This post is to fix a bug enhance the functionality in the original Blog Post titled “MVC2 Validation and Testing” at the following link. 
http://blog.overridethis.com/blog/post/2010/04/22/MVC2-Model-Validation-and-Testing-Scenarios.aspx


A while back I wrote about testing Controller Actions that rely on MVC2’s new Model Validation.  I had been using the technique described in the post for a while on most of my MVC2 applications without running into any significant issue until I tried to combine validators on a single property of my Model.  The following are the modified testing scenarios that would not work with the code I provided in my originally post.  Apparently, the code I wrote originally does not target all validators that are applied through Metadata.

 

namespace WebSite.Services {

    public interface ICommentService {
        void AddComment(string email, string message);
    }

}
namespace WebSite.Models {
    
    using System.ComponentModel.DataAnnotations;

    public class AddCommentRequest {
        private const string EMAIL_REGEX = 
           @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
            + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
            + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
            + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";
        [Required, RegularExpression(EMAIL_REGEX)]
        public string Email { get; set; }
        [Required]
        public string Message { get; set; }
    }

    public class AddCommentResult {
        public bool Success { get; set; }
        public string Message { get; set; }
    }
}
namespace WebSite.Controllers {

    using System.Web.Mvc;
    using Models;
    using Services;

    public class CommentController : Controller {

        private readonly ICommentService service;

        public CommentController() {

        }

        public CommentController(ICommentService service) {
            this.service = service;
        }

        [HttpPost]
        public ActionResult AddComment(AddCommentRequest request) {
            if (ModelState.IsValid) {
                this.service.AddComment(request.Email, request.Message);
                return Json(new AddCommentResult {Success = true, Message = "Success"});
            }
            return Json(
                new AddCommentResult { 
                        Success = false, 
                        Message = "The 'message' is a required field." 
                });
        }
    }
}

 

The following Test validate the Model Validation functionality enforce and needless to say if we use the original ControllerExtension for validation we get less than ideal results.

 

[TestFixture]
public class CommentControllerTests {

    private string VALID_MESSAGE = "SOME MESSAGE!";
    private string VALID_EMAIL   = "someemail@yahoo.com";
    private string NOT_VALID_MESSAGE = string.Empty;
    private string NOT_VALID_EMAIL   = "someemail@@@@@@c";
    
    [Test]
    public void CommentControllerCanAddValidMessage() {
        Assert.IsTrue(this.HttpPostToAddComments(VALID_EMAIL, VALID_MESSAGE).Success);
    }

    [Test]
    public void CommentControllerCannotAddWithoutValidMessage() {
        Assert.IsTrue(this.HttpPostToAddComments(VALID_EMAIL, NOT_VALID_MESSAGE).Success);
    }    

    [Test]
    public void CommentControllerCannotAddWithoutRequiredEmail() {
        Assert.IsTrue(this.HttpPostToAddComments("", VALID_MESSAGE).Success);
    }    

    [Test]
    public void CommentControllerCannotAddWithourValidEmailAddress() {
        Assert.IsTrue(this.HttpPostToAddComments(NOT_VALID_EMAIL, VALID_MESSAGE).Success);
    }

    private AddCommentResult HttpPostToAddComments(string email, string message) {
        
        var mockOfICommentService = new Mock<ICommentService>();
        mockOfICommentService.Setup(m => m.AddComment(VALID_EMAIL, VALID_MESSAGE)).AtMostOnce();
        var model = new AddCommentRequest {Email = email, Message = message};
        var controller = new CommentController(mockOfICommentService.Object);
        var result = controller
		.CallWithModelValidation(c => c.AddComment(model), model);
        mockOfICommentService.Verify();
        return (AddCommentResult)((JsonResult) result).Data;
    }
}

 

This time around I feel like I did better research to find a suitable solution by looking at the ASP.NET MVC 2 source code and its tests.   In my original post, I had overlooked a couple of reusable tools already in place in the ASP.NET MVC source code that would have made my work a whole lot easier like the ModelMetadataProviders, and DataAnnotationsModelValidatorProvider.   Of course, there is always room for improvement, but the following is the refactored ControllerExtensions class that allows for all the previous tests to go green.

 

public static class ControllerExtensions {

    public static ActionResult CallWithModelValidation<C, R, T>(this C controller
           , Func<C, R> action
           , T model)
        where C : Controller
        where R : ActionResult
        where T : class {
        DataAnnotationsModelValidatorProvider provider = new DataAnnotationsModelValidatorProvider();
        IEnumerable<ModelMetadata> metadata = ModelMetadataProviders
			.Current
			.GetMetadataForProperties(model, typeof(T));
        foreach (ModelMetadata modelMetadata in metadata) {
            IEnumerable<ModelValidator> validators = provider
				.GetValidators(modelMetadata, new ControllerContext());
            foreach (ModelValidator validator in validators) {
                IEnumerable<ModelValidationResult> results = validator.Validate(model);
                foreach (ModelValidationResult result in results)
                    controller.ModelState.AddModelError(modelMetadata.PropertyName, result.Message);
            }
        }
        return action(controller);
    }
}