0

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?

Buzz
  • 321
  • 2
  • 3
  • 20

2 Answers2

1

I would implement a Singleton Pattern https://msdn.microsoft.com/en-us/library/ff650316.aspx

If you are using any Dependency injection container then all of them have support for Singleton Instance

pateketu
  • 451
  • 2
  • 8
  • It's best to add a concise example of a basic singleton, instead of just the URL. URLs might change or go offline, rendering your answer useless after a while. I'd add it myself, but the comments don't allow for nice formatting :) – Flater Mar 10 '15 at 09:04
  • A singleton is considered an anti-pattern, it breaks testability and is the cause tightly coupled code. Better to use an IoC container and it's life-time managers for it (i.e. Unity and it's `ContainerControlledLifetimeManager`). It will give you a singleton-like object w/o the dependency on the concrete class or a static factory – Tseng Mar 10 '15 at 09:15
  • @ Tseng yes agree, that's why I mentioned the DI container, if the original poster is using any! – pateketu Mar 10 '15 at 11:27
0

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.

Tseng
  • 61,549
  • 15
  • 193
  • 205
  • Hi Tseng, thank you for your advice. I'am newbie on MVC. I need more detail on how to use it. Let say I have the object class name 'driver'. Where to create it? Is it in app_start in global.asax or where? And how to access it within the controller? – Buzz Mar 11 '15 at 01:54
  • And please note that the object has events that I need to play with also. Does this method by using container support this? Thanks. – Buzz Mar 11 '15 at 02:01
  • That's a bit to broad to answer it. But the "composition root" is the place where you compose your object graph. The place varies depending on application type. In ASP.NET it's the global.aspx, in Console app the Main(...) method etc. Mark Seeman has a nice explaination of it (see http://blog.ploeh.dk/2011/07/28/CompositionRoot/). He's also very active here on SO on Dependency Injection and wrote a book about it. But generally you create a static method and do your registrations there – Tseng Mar 11 '15 at 02:42
  • Thanks Tseng. I have read the pros & cons using singleton and I think using container would be the best solution so far. I will try this one. – Buzz Mar 11 '15 at 03:46