How to integrate Munq IOC Container Version 3 in ASP.NET MVC 3

How to integrate Munq IOC Container Version 3 in ASP.NET MVC 3

Munq IOC Container Version 3 has been released on CodePlex and as a NuGet package. This article demonstrates how to integrate the IOC Container into an ASP.NET MVC3 project.

Introduction

Version 3 of the Munq IOC Container adds a number of features including documentation and NuGet packaging. The Munq source is maintained on CodePlex. This article demonstrates how to integrate the Munq IOC Container into an ASP.NET MVC project using the NuGet package.

For my example, I will refactor the AccountController to use Dependency Injection and the Munq IOC Container. At the end, I will have:

  • Integrated the Munq IOC Container into an ASP.NET project.
  • Refactored the AccountController to use Dependency Injection.
  • Initialized the IOC Container with the required Registrations.
  • Updated the Unit Tests.

The final solution will allow you to easily replace the IFormsAuthenticationService and IMembershipService implementations through the IOC Container configuration. As an added bonus, you can replace the instance of the MembershipProvider used by the AccountMembershipService.

Background

As a result of the feedback and suggestion I have received, and the need to use the IOC Container with ASP.NET MVC3, I have released an updated version of Munq. In addition to the core IOC Container, there is an implementation of the ASP.NET MVC3 IDependencyResolver and the Common Service Locator. All three are available as NuGet packages.

Probably, the most important additions to the Munq IOC container are:

  • The automatic resolution of classes to the public constructor with the most parameters. This means that a class is resolved by the class type, it does not need to be registered with the container.
  • Registration by types. Using the above, you can register a interface implementation in the form container.Register<IMyType, MyClass>();

Show Me the Code

The first thing to do is to create a MVC3 project, selecting the Internet Application option. Also select ASP.NET as the view engine, and check the box for unit tests. This creates a simple starting point that includes a Home page, an About page, and Form based authentication using SQL Express.

Build and run the application, just so we know it works. Also, run the unit test to verify they pass.

If we take a look at the AccountController.cs file, we see that the dependencies for this controller are wired up in the Initialize method:

public IFormsAuthenticationService FormsService { get; set; }
public IMembershipService MembershipService { get; set; }

protected override void Initialize(RequestContext requestContext)
{
    if (FormsService == null)      { FormsService = new FormsAuthenticationService(); }
    if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

    base.Initialize(requestContext);
}

We want to change this to use Dependency Injection so we will remove this method and add a constructor which has the authentication and membership services as parameters. Also, the FormsService and MembershipService properties expose implementation details that should not be needed by users of the controller. We won't fix that right now, as it will break a number of the unit tests, and isn't important in showing how to get the Dependency Injection working.

A quick refactoring and we end up with:

public IFormsAuthenticationService FormsService      { get; set; }
public IMembershipService          MembershipService { get; set; }

public AccountController(IFormsAuthenticationService formsService,
                                IMembershipService membershipService)
{
    FormsService      = formsService;
    MembershipService = membershipService;
}

Build the solution and we get an error in the unit test stating that AccountController does not have a constructor with no parameters.

Modify the GetAccountController method in AccountControllerTest.cs to:

private static AccountController GetAccountController()
{
    RequestContext requestContext = 
        new RequestContext(new MockHttpContext(), new RouteData());
    AccountController controller = 
        new AccountController(new MockFormsAuthenticationService(),
                  new MockMembershipService())
    {
        Url = new UrlHelper(requestContext),
    };
    controller.ControllerContext = new ControllerContext()
    {
        Controller = controller,
        RequestContext = requestContext
    };
    return controller;
}

Also, the AccountMembershipService class, defined in Models/AccountModels.cs has a parameterless constructor. Remove it. Also change the other constructor as shown below:

public class AccountMembershipService : IMembershipService
{
    private readonly MembershipProvider _provider;

    public AccountMembershipService(MembershipProvider provider)
    {
        _provider = provider;
    }

    ...

We now have a successful build and all the tests still pass, but when we run it, we get an error when we click on the logon link. The error...

System.MissingMethodException: No parameterless constructor defined for this object.

...which as the stack trace explains is caused by the AccountController.

Now, we need to add the IOC Container. Fortunately, I have created a NuGet package for using the Munq IOC Container in MVC3. I am assuming that you have NuGet installed in your copy of Visual Studio. Right click on the MuncMvc3Sample project and select Add Library Package Reference .... This will bring up the NuGet dialog. Search for Munq in the online packages. You will see three choices. Install the Munq.MVC3 package.

How to integrate Munq IOC Container Version 3 in ASP.NET MVC 3

This installs and adds references to:

  • Munq.IocContainer.dll (the Munq IOC Container)
  • Munq.MVC3.dll (contains the MunqDependencyResolver which implements the System.Web.Mvc.IDependency interface)
  • WebActivator.dll (allows the MunqDependencyResolver to be automatically wired up)

Additionally, a directory App_Start is created and contains one file, MunqMvc3Startup.cs. This file contains the code to configure MVC3 to use the Munq IOC Container for its dependency resolution tasks.

using System.Web.Mvc;
using Munq.MVC3;

[assembly: WebActivator.PreApplicationStartMethod
    (typeof(MunqMvc3Sample.App_Start.MunqMvc3Startup), "PreStart")]
namespace MunqMvc3Sample.App_Start {
    public static class MunqMvc3Startup {
        public static void PreStart() {
            DependencyResolver.SetResolver(new MunqDependencyResolver());
            var ioc = MunqDependencyResolver.Container;

            // TODO: Register Dependencies
            // ioc.Register<IMyRepository, MyRepository>();
        }
    }
}

Make sure the Development Web Server is stopped, so the startup code is executed. Now try and build and run. We still get the error. This is because we haven't Registered the implementations for IFormsService and IMembershipService. Because of this, MVC falls back to attempting to create the AccountController with the parameterless constructor, which does not exist. In MunqMvc3Startup.cs, register the services.

using System.Web.Mvc;
using Munq.MVC3;
using MunqMvc3Sample.Models;

[assembly: WebActivator.PreApplicationStartMethod(
    typeof(MunqMvc3Sample.App_Start.MunqMvc3Startup), "PreStart")]

namespace MunqMvc3Sample.App_Start {
    public static class MunqMvc3Startup {
        public static void PreStart() {
            DependencyResolver.SetResolver(new MunqDependencyResolver());
            var ioc = MunqDependencyResolver.Container;

            // TODO: Register Dependencies
            // ioc.Register<IMyRepository, MyRepository>();

            // setup AccountController's dependencies
            ioc.Register<IFormsAuthenticationService, FormsAuthenticationService>();
            ioc.Register<IMembershipService, AccountMembershipService>();

            // AccountMembershipService needs a MembershipProvider
            ioc.Register<MembershipProvider>(c => Membership.Provider);
        }
    }
}

Again, stop the Development Server and then build and run. Now, when you click run, the login form is displayed. MvC3 is now using Munq to resolve the dependencies. Notice that we did not have to register the AccountController class itself. For classes, Munq will attempt to resolve using the constructor with the most parameters. This is exactly what MVC3 requires, and why the feature was added to Munq.

This means, if you add or delete parameters (dependencies) to a Controller's constructor, it will still be resolved as long as the dependencies are Registered or are classes.

Next, I want to refactor out FormsService and MembershipService properties from the AccountController class. I'm using CodeRush, so the refactoring is pretty easy.

private IFormsAuthenticationService _formsService;
private IMembershipService          _membershipService;

public AccountController(IFormsAuthenticationService formsService,
                                    IMembershipService membershipService)
{
    _formsService      = formsService;
    _membershipService = membershipService;
}

Building now results in a number of errors in the unit test that were using this property. I will not detail the changes here, but you can see them in the source files included.

Conclusion

The result of this example is a Visual Studio project that can be used as a template for future development with ASP.NET MVC3 and the Munq IOC Container.

asp-net dotnet web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire ASP.Net Developers

Looking to outsource your asp dot net development requirement? ASP.Net is a special feature of the DOT Net framework created by Microsoft. At [HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io"), we have a team of experienced...

Blazor for ASP.NET Web Forms Developers PDF

In this blog post, I will share the Free e-book: Blazor for ASP.NET Web Forms Developers PDF. This book is great for ASP.NET Web Forms developers looking for guidelines. As well as strategies for migrating their existing apps to a modern, open-source, and cross-platform web framework.

8 Reasons Why PHP and .NET Rule the World of Web Development

Building a website is the first step in the path of a successful business. For web development, PHP and .Net are the foremost languages. If any company wants to succeed in the market, it needs to strengthen its digital presence. Though social media provides a place to gain some attention, it is impossible to create a brand without an official web page. This is why businesses hire firms offering web development services to get their website designed, which would enable them to get as much traction as possible.

Free e-book: Blazor for ASP.NET Web Forms Developers

Releasing new e-book: Blazor for ASP.NET Web Forms Developers. It covers guidelines and strategies for migrating existing apps to a modern web framework.

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...