0

Мне нужно объявить объект в приложении MVC. Этот объект потребляет память, поэтому мне нужно, чтобы она была создана один раз, когда приложение запускается и не будет уничтожено до повторного использования. Один и тот же экземпляр объекта также должен быть доступен через приложение внутри контроллеров.MVC Single Instance Object

Я использовал этот объект в службе WCF, используя InstanceContextMode.Single и отлично работает. Но как с MVC?

ответ

0

Как одиночки в основном считаются анти-моделью. Они делают ваш код трудным для тестирования (используя mocks и stub) и создают тесно связанный код.

Поскольку это очень плохая практика, вам лучше использовать контейнер IoC (Unity, SimpleIoC, Autofac и т. Д.) Для управления сроком службы ваших контейнеров. В Unity 3 IoC container есть менеджер времени жизни ContainerControlledLifetimeManager, где объекты создаются один раз, и тот же экземпляр возвращается для срока службы контейнера.

В корне вашей композиции вы можете либо сделать (используя интерфейс IMemoryConsumingService, чтобы избежать жесткой связи). Затем просто введите его в свои контроллеры и службы. Пример для Unity 3 (другие IoC имеют аналогичную процедуру).

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

или

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

Edit:

При установке Unity 3.5 + Unity MVC Bootstraper вы в основном готовы пойти на это.

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); 
    } 
} 

Внутри RegisterType метода вы делаете вашу регистрацию (пожалуйста, проверьте ссылку ниже документации, IoC это сложно объяснить это в пределах простого ответа). Новые nugetpackages готовятся к работе без каких-либо дальнейших изменений (кроме добавления регистраций). Не нужно менять Global.asax, как это требовалось в первые годы Unity.

+0

Привет Ценг, спасибо за ваш совет. Я новичок в MVC. Мне нужно больше деталей о том, как его использовать. Скажем, у меня есть имя класса объекта «driver». Где его создать? Это в app_start в global.asax или где? И как получить доступ к нему в контроллере? –

+0

И обратите внимание, что у объекта есть события, в которых мне также нужно играть. Поддерживает ли этот метод использование контейнера? Благодарю. –

+0

Это немного к широкому, чтобы ответить на него. Но «составной корень» - это место, где вы составляете свой графический объект. Место варьируется в зависимости от типа приложения. В ASP.NET это global.aspx, в приложении Console - метод Main (...) и т. Д. Mark Seeman имеет приятное объяснение (см. Http://blog.ploeh.dk/2011/07/28/CompositionRoot /).Он также очень активен здесь, на SO on Dependency Injection, и написал книгу об этом. Но обычно вы создаете статический метод и делаете свои регистрации там – Tseng

1

Я бы реализовать одноплодный шаблон https://msdn.microsoft.com/en-us/library/ff650316.aspx

Если вы используете какой-либо инъекцию контейнера зависимостей, то все они имеют поддержку Singleton Instance

+0

Лучше всего добавить примерный простой синглтон, а не только URL-адрес. URL-адреса могут меняться или переходить в автономный режим, что делает ваш ответ бесполезным через некоторое время. Я бы добавил его сам, но комментарии не позволяют красивого форматирования :) – Flater

+0

Синглтон считается анти-шаблоном, он ломает тестируемость и является причиной тесно связанного кода. Лучше использовать контейнер IoC и его управляющие жизненным циклом (т. Е. Unity, и это «ContainerControlledLifetimeManager»). Он даст вам одноэлементный объект без зависимости от конкретного класса или статической фабрики – Tseng

+0

@ Ценг да согласен, поэтому я упомянул контейнер DI, если оригинальный плакат использует любой! – pateketu

 Смежные вопросы

  • Нет связанных вопросов^_^