Как одиночки в основном считаются анти-моделью. Они делают ваш код трудным для тестирования (используя 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.
Привет Ценг, спасибо за ваш совет. Я новичок в MVC. Мне нужно больше деталей о том, как его использовать. Скажем, у меня есть имя класса объекта «driver». Где его создать? Это в app_start в global.asax или где? И как получить доступ к нему в контроллере? –
И обратите внимание, что у объекта есть события, в которых мне также нужно играть. Поддерживает ли этот метод использование контейнера? Благодарю. –
Это немного к широкому, чтобы ответить на него. Но «составной корень» - это место, где вы составляете свой графический объект. Место варьируется в зависимости от типа приложения. В ASP.NET это global.aspx, в приложении Console - метод Main (...) и т. Д. Mark Seeman имеет приятное объяснение (см. Http://blog.ploeh.dk/2011/07/28/CompositionRoot /).Он также очень активен здесь, на SO on Dependency Injection, и написал книгу об этом. Но обычно вы создаете статический метод и делаете свои регистрации там – Tseng