Какие контейнеры IoC поддерживают возврат определенных объектов на основе идентификаторов? - PullRequest
0 голосов
/ 11 февраля 2011

Я только сейчас начинаю экспериментировать с контейнерами IoC. В настоящее время я использую собственную фабрику для создания своих моделей ViewModels, которые бывают двух видов: синглтон и на основе идентификатора. Другими словами, мое приложение (по определению) имеет только одну комнату за раз, и, следовательно, только одну RoomViewModel, но в этой комнате может находиться много пользователей, поэтому мне нужно много UserViewModel. Но я хочу убедиться, что, скажем, для пользователя с UserId = "johnsmith" когда-либо создается только одна UserViewModel, и любая попытка получить эту UserViewModel будет возвращать тот же экземпляр.

Я не знаю, поможет ли это объяснить вещи или запутать их, но этот метод я сейчас использую для этого:

public ViewModelType GetViewModelByKey<ViewModelType, KeyType>(KeyType key) 
        where ViewModelType : AlantaViewModelBase, new()
    {
        IDictionary dictionary;
        var type = typeof(ViewModelType);
        if (!keyedViewModelDictionaries.TryGetValue(type, out dictionary))
        {
            dictionary = new Dictionary<KeyType, ViewModelType>();
            keyedViewModelDictionaries.Add(type, dictionary);
        }
        var viewModels = (Dictionary<KeyType, ViewModelType>)dictionary;
        ViewModelType vm;
        if (!viewModels.TryGetValue(key, out vm))
        {
            vm = new ViewModelType();
            viewModels.Add(key, vm);
            vm.Initialize(this);
        }
        return vm;
    }

Это означает, что эти два вызова будут возвращать отдельные экземпляры:

// Get VM for user.UserId="john";
var userVM1 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("john");
// Get VM for user.UserId="suzie";
var userVM2 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("suzie");

Но они вернут один и тот же экземпляр:

// Get the same VM for user.UserId="bob";
var userVM1 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("bob");
var userVM2 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("bob");

Возможность сделать это решает множество проблем с привязкой данных и синхронизацией, поэтому я не собираюсь легко отказываться от паттерна.

Но я бы хотел, если возможно, перейти к стандартному контейнеру IoC, поскольку, предположительно, они имеют больше функций, не требуют специальных типов и, безусловно, более стандартизированы. Но, читая их, я не обнаружил никаких очевидных признаков того, что они поддерживают мой второй подход. Другими словами, все они поддерживают стандартные два стиля жизни (синглтон и переходный процесс), но я хочу что-то немного другое: синглтон на объектную идентичность. Поддерживают ли стандартные контейнеры IoC это? Как? Какие из них?

Извините, если это основной вопрос.

Ответы [ 2 ]

1 голос
/ 11 февраля 2011

MEF поддерживает это через Экспорт с использованием «Название контракта».Это позволяет экспортировать и импортировать с указанными именами контрактов:

[Import("bob", typeof(UserViewModel)]
public UserViewModel bobViewModel { get; set; }

Под редакцией Кена Смита
См. Обсуждение ниже для нашего окончательного вывода о том, что контейнеры IoC не поддерживаюттакого рода поведение из коробки, и, возможно, на самом деле не предназначены для решения этой проблемы.

0 голосов
/ 11 февраля 2011

Spring.NET, безусловно, поддерживает не одноэлементные именованные объекты.Singleton - это поведение DI по умолчанию, но вы также можете указать, что отдельные экземпляры также должны создаваться.

См. Документацию здесь .

...