asp.net-mvcmodel-view-controllerinstancecontextmode

MVC Single Instance Object


I need to declare an object in MVC app. This object consume memory so I need it to be created once when app start and won't be destroy until recycled. The same instance of the object also should be able accessed across application within controllers.

I have used this object in WCF service by using InstanceContextMode.Single and works great. But how with MVC?


Solution

  • As singletons are largely considered an anti-pattern. They make your code hard to test (using mocks and stubs) and create tightly coupled code.

    Since this is very bad practice, you are better off using an IoC container (Unity, SimpleIoC, Autofac, etc.) to manage the lifetime of your containers. The Unity 3 IoC container has an ContainerControlledLifetimeManager lifetime manager where objects are created once and the same instance is returned for the lifetime of the container.

    In your composition root you could either do (using IMemoryConsumingService interface to avoid tight coupling). Then just inject it into your controllers and services. Example for Unity 3 (other IoC have similar procedure).

    MemoryConsumingService service = new MemoryConsumingService();
    container.RegisterInstance<IMemoryConsumingService>(service);
    

    or

    container.RegisterType<IMemoryConsumingService, MemoryConsumingService(new ContainerControlledLifetimeManager());
    

    Edit:

    When you install Unity 3.5 + Unity MVC Bootstraper you are basically ready to go for it.

    public class UnityConfig
    {
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });
    
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
    
        public static void RegisterTypes(IUnityContainer container)
        {
            container.RegisterType<IDriver, Driver>(new ContainerControlledLifetimeManager());
    
            // OR 
            IDriver driver = new Driver();
            container.RegisterInstance<IDriver>(driver);
        }
    }
    

    Inside the RegisterType method you do your registration (please check out the documentation link below, IoC is to complicated to explain it within an simple answer). The newer nugetpackages get you ready to go, without any further changes (except adding registrations). No need to change the Global.asax as it was required in the early years of Unity.