Click here to Skip to main content
Click here to Skip to main content

Using Munq IOC Container Version 3 in ASP.NET MVC 3

By , 2 Apr 2011
 

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

Previously, I've written about the Munq IOC container

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.

Munq IOC on NuGet - Click to enlarge image

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.

History

  • First Release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Matthew Dennis
Software Developer (Senior) The Code Project
Canada Canada
Member
Matthew works on improving the performance and experience of the Code Project site for users, clients, and administrators.
 
Matthew has more years of software develeopment, QA and architecture experience under his belt than he likes to admit. He gradutated for the University of Waterloo with a B.Sc. in Electrical Engineering. He started out developing micro-processor based hardware and software including compilers and operating systems.
His current focus is on .NET web development including jQuery, Webforms, MVC, AJAX, and patterns and practices for creating better websites.
He is the author of the Munq IOC, the fastest ASP.NET focused IOC Container.
His non-programming passions include golf, pool, curling, reading and building stuff for the house.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberMatthew At Home23 Nov '12 - 5:48 
blah
QuestionMultiple user login issue using MUNQmemberShyamSunderVashista25 Jul '12 - 3:29 
Hi Dennis
Thanks for such an great article.
 
I am using the MUNQ.DI/ EF/ Facade in BL and registring in global.aspx's Application_PreRequestHandlerExecute event for my application and getting error when multiple users logging application. It is showing one user data to other user data panel
 
Can you suggest where I am doing wrong?
 
Shyam
AnswerRe: Multiple user login issue using MUNQadminMatthew Dennis25 Jul '12 - 6:53 
I really can't help without seeing the code in question.
 
It's likely you are registering the DbContext or connection in Munq as a container (application) singleton, where they should be Request Singletons. Unfortunately, the Request Lifetime Manager uses the Request.Items collection, so using it in the PreRequestHandelerExecute event probably will not work.
 
I would be happy to look at what you are doing and make any suggestions I can come up with.
GeneralRe: Multiple user login issue using MUNQmemberShyamSunderVashista25 Jul '12 - 19:01 
Hi Dennis
 
Thanks for support
Here I am pasting my code
Facade.cs
<pre lang="c#">
 
using System;
using System.Collections.Generic;
using System.Web;
using Corecon.Aspect;
using Corecon.Business.Facade.Context;
using Corecon.DataAccess.Context;
using Corecon.DataAccess.Repository.IMPL;
using Corecon.DataAccess.Repository.Interface;
using Corecon.Util;
using Microsoft.Practices.Unity;
 
namespace Corecon.Business.Facade
{
 
    public partial class Facade : IDisposable
    {
        private Dictionary<int, IDisposable> _disposableCache = new Dictionary<int, IDisposable>();
 
        private T Resolve<T>(T resolver)
            where T : IDisposable
        {
            int hashcode = typeof(T).GetHashCode();
            if (_disposableCache.ContainsKey(hashcode))
                return (T)_disposableCache[hashcode];
            else
            {
                var item = resolver;
                _disposableCache.Add(hashcode, item);
                return item;
            }
        }
 
        #region Fields
 
        private IColumnRepository columnRepository { get { return Resolve<IColumnRepository>(columnRepositoryResolver); } }
        private IPageRepository pageRepository { get { return Resolve<IPageRepository>(pageRepositoryResolver); } }
        private IUserRepository userRepository { get { return Resolve<IUserRepository>(userRepositoryResolver); } }
        private IWidgetInstanceRepository widgetInstanceRepository { get { return Resolve<IWidgetInstanceRepository>(widgetInstanceRepositoryResolver); } }
        private IWidgetRepository widgetRepository { get { return Resolve<IWidgetRepository>(widgetRepositoryResolver); } }
        private IWidgetZoneRepository widgetZoneRepository { get { return Resolve<IWidgetZoneRepository>(widgetZoneRepositoryResolver); } }
        private IUserSettingRepository userSettingRepository { get { return Resolve<IUserSettingRepository>(userSettingRepositoryResolver); } }
 
        // for DB database
        private ICommonRepository commomRepository { get { return Resolve<ICommonRepository>(commonRepositoryResolver); } }
        private IDocumentationRepository documentaionRepository { get { return Resolve<IDocumentationRepository>(documentaionRepositoryResolver); } }
        private ICorrespondenceRepository correspondenceRepository { get { return Resolve<ICorrespondenceRepository>(correspondenceRepositoryResolver); } }
        private IProcurementRepository procurementRepository { get { return Resolve<IProcurementRepository>(procurementRepositoryResolver); } }
        private IContractChangesRepository contractChangesRepository { get { return Resolve<IContractChangesRepository>(contractChangesRepositoryResolver); } }
 

        private readonly IColumnRepository columnRepositoryResolver;
        private readonly IPageRepository pageRepositoryResolver;
        private readonly IUserRepository userRepositoryResolver;
        private readonly IWidgetInstanceRepository widgetInstanceRepositoryResolver;
        private readonly IWidgetRepository widgetRepositoryResolver;
        private readonly IWidgetZoneRepository widgetZoneRepositoryResolver;
        private readonly IWidgetsInRolesRepository widgetsInRolesRepositoryResolver;
        private readonly IUserSettingRepository userSettingRepositoryResolver;
 
        // for DB database
        private readonly ICommonRepository commonRepositoryResolver;
        private readonly IDocumentationRepository documentaionRepositoryResolver;
        private readonly ICorrespondenceRepository correspondenceRepositoryResolver;
        private readonly IProcurementRepository procurementRepositoryResolver;
        private readonly IContractChangesRepository contractChangesRepositoryResolver;
 

 
//private readonly Func<IColumnRepository> columnRepositoryResolver;
        //private readonly Func<IPageRepository> pageRepositoryResolver;
        //private readonly Func<IUserRepository> userRepositoryResolver;
        //private readonly Func<IWidgetInstanceRepository> widgetInstanceRepositoryResolver;
        //private readonly Func<IWidgetRepository> widgetRepositoryResolver;
        //private readonly Func<IWidgetZoneRepository> widgetZoneRepositoryResolver;
        //private readonly Func<IWidgetsInRolesRepository> widgetsInRolesRepositoryResolver;
        //private readonly Func<IUserSettingRepository> userSettingRepositoryResolver;
 
        //// for DB database
        //private readonly Func<ICommonRepository> commonRepositoryResolver;
        //private readonly Func<IDocumentationRepository> documentaionRepositoryResolver;
        //private readonly Func<ICorrespondenceRepository> correspondenceRepositoryResolver;
        //private readonly Func<IProcurementRepository> procurementRepositoryResolver;
        //private readonly Func<IContractChangesRepository>contractChangesRepositoryResolver;
 

        #endregion Fields
 
        #region Constructors
 
        public Facade()
            : this(AppContext.GetContext(HttpContext.Current))
        {
        }
 
        public Facade(AppContext context) :
            this(context,
            Services.Get<IColumnRepository>(),
            Services.Get<IPageRepository>(),
            Services.Get<IUserRepository>(),
            Services.Get<IWidgetRepository>(),
            Services.Get<IWidgetInstanceRepository>(),
            Services.Get<IWidgetZoneRepository>(),
            Services.Get<IWidgetsInRolesRepository>(),
            Services.Get<IUserSettingRepository>(),
            Services.Get<ICommonRepository>(),
            Services.Get<IDocumentationRepository>(),
            Services.Get<ICorrespondenceRepository>(),
            Services.Get<IProcurementRepository>(),
            Services.Get<IContractChangesRepository>())
        {
            this.Context = context;
        }
 

        public Facade(AppContext context,
            IColumnRepository columnRepository,
           IPageRepository pageRepository,
            IUserRepository userRepository,
           IWidgetRepository widgetRepository,
            IWidgetInstanceRepository widgetInstanceRepository,
            IWidgetZoneRepository widgetZoneRepository,
            IWidgetsInRolesRepository widgetsInRolesRepository,
            IUserSettingRepository userSettingRepository,
            ICommonRepository commonRepository,
            IDocumentationRepository documentaionRepository,
            ICorrespondenceRepository correspondenceRepository,
           IProcurementRepository procurementRepository,
           IContractChangesRepository contractRepository
            )
        {
            this.columnRepositoryResolver = columnRepository;
            this.pageRepositoryResolver = pageRepository;
            this.userRepositoryResolver = userRepository;
            this.widgetRepositoryResolver = widgetRepository;
            this.widgetInstanceRepositoryResolver = widgetInstanceRepository;
            this.widgetZoneRepositoryResolver = widgetZoneRepository;
            this.widgetsInRolesRepositoryResolver = widgetsInRolesRepository;
            this.userSettingRepositoryResolver = userSettingRepository;
            this.commonRepositoryResolver = commonRepository;
            this.documentaionRepositoryResolver = documentaionRepository;
            this.correspondenceRepositoryResolver = correspondenceRepository;
            this.procurementRepositoryResolver = procurementRepository;
            this.contractChangesRepositoryResolver = contractRepository;
        }
        //public Facade(AppContext context,
        //   Func<IColumnRepository> columnRepository,
        //   Func<IPageRepository> pageRepository,
        //   Func<IUserRepository> userRepository,
        //   Func<IWidgetRepository> widgetRepository,
        //   Func<IWidgetInstanceRepository> widgetInstanceRepository,
        //   Func<IWidgetZoneRepository> widgetZoneRepository,
        //   Func<IWidgetsInRolesRepository> widgetsInRolesRepository,
        //   Func<IUserSettingRepository> userSettingRepository,
        //   Func<ICommonRepository> commonRepository,
        //   Func<IDocumentationRepository> documentaionRepository,
        //   Func<ICorrespondenceRepository> correspondenceRepository,
        //   Func<IProcurementRepository> procurementRepository,
        //   Func<IContractChangesRepository> contractRepository
        //   )
        //{
        //    this.columnRepositoryResolver = columnRepository;
        //    this.pageRepositoryResolver = pageRepository;
        //    this.userRepositoryResolver = userRepository;
        //    this.widgetRepositoryResolver = widgetRepository;
        //    this.widgetInstanceRepositoryResolver = widgetInstanceRepository;
        //    this.widgetZoneRepositoryResolver = widgetZoneRepository;
        //    this.widgetsInRolesRepositoryResolver = widgetsInRolesRepository;
        //    this.userSettingRepositoryResolver = userSettingRepository;
        //    this.commonRepositoryResolver = commonRepository;
        //    this.documentaionRepositoryResolver = documentaionRepository;
        //    this.correspondenceRepositoryResolver = correspondenceRepository;
        //    this.procurementRepositoryResolver = procurementRepository;
        //    this.contractChangesRepositoryResolver = contractRepository;
        //}
 

        #endregion Constructors
 
        #region Properties
 
        public AppContext Context
        {
            get;
            set;
        }
 
        #endregion Properties
 
        #region Methods
 
        public static void BootStrap(string orgId)
        {
            Aspect.Aspect.Define
                .Log(new EntLibLogger(), "Register default types in Unity")
                .Do(() =>
                {
                    CacheSetup.Register();
 

                    Services.RegisterInstance<ILogger>(r => new EntLibLogger());
 
                    var connection = CoreconDBDataContext.GetConnectionString();
                    connection = connection.Replace("OrgId", orgId);
 
                    // .RegisterType<IDatabase, CoreconContext>(new InjectionConstructor(connection))
 
                    Services.RegisterType<ICCMaster>(r => new CCMasterContext());
                    Services.RegisterType<ICoreconDB>(r => new CoreconDBDataContext(connection));
 

                    // repo under master db
                    Services.RegisterInstance<IColumnRepository>(r => new ColumnRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IPageRepository>(r => new PageRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IUserRepository>(r => new UserRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IWidgetRepository>(r => new WidgetRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IWidgetInstanceRepository>(r => new WidgetInstanceRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IWidgetZoneRepository>(r => new WidgetZoneRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IWidgetsInRolesRepository>(r => new WidgetsInRolesRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IUserSettingRepository>(r => new UserSettingRepository(
                        r.Resolve<ICCMaster>(), r.Resolve<ICache>()));
 
                    // repo under CoreconDB database
 
                    Services.RegisterInstance<ICommonRepository>(r => new CommonRepository(
                       r.Resolve<ICoreconDB>(), r.Resolve<ICache>()));
 
                    Services.RegisterInstance<IDocumentationRepository>(r => new DocumentationRepository(
                     r.Resolve<ICoreconDB>(), r.Resolve<ICache>()));
                    Services.RegisterInstance<ICorrespondenceRepository>(r => new CorrespondenceRepository(
                     r.Resolve<ICoreconDB>(), r.Resolve<ICache>()));
                    Services.RegisterInstance<IProcurementRepository>(r => new ProcurementRepository(
                     r.Resolve<ICoreconDB>(), r.Resolve<ICache>()));
                    Services.RegisterInstance<IContractChangesRepository>(r => new ContractChangesRepository(
                    r.Resolve<ICoreconDB>(), r.Resolve<ICache>()));
                    Corecon.Util.Services.RegisterType<Facade>(
                        c =>
                        {
                            var context = HttpContext.Current;
                            if (null == context)
                                return new Facade(new AppContext(0, string.Empty));
                            else
                                return context.Items[typeof(Facade).FullName] as Facade;
                        });
                });
        }
        private bool _disposed = false;
        public void Dispose()
        {
            if (_disposed) return;
 
            _disposableCache.Values.Each(d => d.Dispose());
            _disposableCache.Clear();
            _disposableCache = null;
 
            _disposed = true;
        }
 
        #endregion Methods
 
    }
}
 
</pre>
 
And for Service.cs
 
<pre lang="c#">
#define MUNQ
 
    using System;
    using Munq.DI;
    using Munq.DI.LifetimeManagers;
using Microsoft.Practices.Unity;
using System.Collections.Generic;
 
namespace Corecon.Util
{
    public class Services
    {
        #region Fields
 
        //private static  ILifetimeManager _containerLifetime =
        //    new ContainerLifetime();
        private static ILifetimeManager _containerLifetime = new Munq.DI.LifetimeManagers.AlwaysNewLifetime();
        private static  Container _container = new Container();
 
        #endregion Fields
 
        #region Methods
 
        public static void Dispose()
        {
            if (null != _container)
            {
                _container.Dispose();
            }
        }
 
        public static IRegistration RegisterType<T>(Func<Container, T> register)
            where T : class
        {
            return _container.Register<T>(register);
        }
 
        public static IRegistration RegisterInstance<T>(Func<Container, T> register)
            where T : class
        {
 
            return _container.RegisterInstance<T>(register(_container))
                .WithLifetimeManager(_containerLifetime);
        }
 
        public static IRegistration RegisterTypeForLazyGet<T>(Func<Container, T> register)
        {
            Func<T> lazyResolve = () => register(_container);
            return _container.RegisterInstance<Func<T>>

QuestionHowTo Munq for micro ORM like Petapoco, Dapper, ServiceStack.OrmLite in class librarymemberMohd Zaki Zakaria5 Apr '12 - 18:05 
Thanks for your great job on Munq and Aimee.Net. Hope you could find extra strength for both projects. I am quite beginner in this IoC and DI and I am using Asp.Net MVC3/4 for my web and mobile projects. My architecture is quite simple as I am using   a class library for my data access (currently evaluating and using Petapoco and ORMLite). Those developers has samples for DI using StructureMap and Funq. Still I could not deal with StructureMap coz it is quite complex and slower than Funq and Funq's developers expect you are expert to use it. I ran into your articles on Munq and I think I would like to give a try. Could give simple code samples on dealing with objects instantiation with micro ORM and latest WCF Web API or using ServiceStack Web Services. My architecture is as follow:   Database--->MicroORM as DAL.dll. DAL.dll--->WCF API/ServiceStack Web Services--->Read/Write/Authenticated End Points--->JSON/XML/etc.---->Clients (web, windows, mobiles). Your help could really benefits many developers like me. Thanks. Vote of 5.
GeneralMy vote of 5memberGrav-Vt21 Oct '11 - 8:20 
Most understandable IOC container I have seen
GeneralTLS should not be used in ASP.NET appsmemberMember 10034801 Jun '11 - 0:21 
Use HttpContext.Current.Items instead - http://www.lhotka.net/WeBlog/PermaLink,guid,019e3c37-38ed-492e-b769-16e1a57fed0a.aspx
GeneralMy vote of 5memberNo_Me4 Apr '11 - 4:26 
Munq is great and NuGet too, so thx for your effort. I�m using it on a customer project (ASP.Net) and a private Project on ASP.Net MVC3.
One Feature i�ve added is a hook for the lifetimemanagers to check if an instance is further valid (some kind of DisposeAware components). So Maybe thats a possible future feature.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 2 Apr 2011
Article Copyright 2011 by Matthew Dennis
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid