Внедрение свойств с Unity вызывает переполнение стека - PullRequest
6 голосов
/ 06 июня 2010

Я давно пользуюсь Unity, но всегда использовал его с инжекцией конструктора.В попытке уменьшить количество классов, которые я должен внедрить в мои модели представлений (так как мои команды полагаются на них), я подумал, что попытаюсь создать концепцию, которая использует Property Injection и тем самым отменить требование для больших списков параметров конструктора.Вот сценарий ...

Я создаю модель представления, в которой есть Команды, расположенные в свойствах, которые каким-то образом используют / обновляют модель представления со шлангом.Я хочу передать экземпляр модели представления в конструкторы команд, расположенных в свойствах моделей представления.Например,

public MainViewModel
{
    public MainViewModel()
    {
        Customers = new ObservableCollection<CustomerViewModel>();
    }        

    [Depedency("LoadCommand")]
    public ICommand LoadCustomersCommand { get; set; }

    public ObservableCollection<CustomerViewModel> Customers { get; private set; }
}

public LoadCustomersCommand : ICommand
{
    public LoadCustomersCommand(MainViewModel mainViewModel)
    {
        //Store view model for later use
    }

    //... implementation
}

//Setup code in App.Xaml

IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<ICommand, LoadCommand>("LoadCommand");
unityContainer.RegisterType<MainViewModel>(new ContainerControlledLifetimeManager());

. Когда я разрешаю класс MainViewModel, я получаю исключение StackOverflow (если Visual Studio вообще возвращается).Теперь я ожидал бы, что Unity сначала создаст экземпляр MainViewModel, поскольку он в основном одноэлементный, затем посмотрим на экземпляр модели представления и создам команду, передающую только что созданную MainViewModel, но, очевидно, я ошибаюсь.

Есть идеи?

1 Ответ

9 голосов
/ 06 июня 2010

Это ошибка Циркулярные ссылки , и, как говорится, ответственность за ее устранение лежит на разработчике. Таким образом, MainViewModel ссылается на LoadCustomersCommand, которая является ссылкой на MainViewModel -> StackOverflow.

Таким образом, единственное, что вы можете сделать, это

public class MainViewModel
{
    public MainViewModel()
    {
        Customers = new ObservableCollection<CustomerViewModel>();
    }        

    //no dependency.
    public ICommand LoadCustomersCommand { get; set; }

    public ObservableCollection<CustomerViewModel> Customers { get; private set; }
}

, и для решения вам необходимо сделать следующее

var mainModel = unityContainer.Resolve<MainViewModel>();
mainModel.LoadCustomersCommand =     unityContainer.Resolve<ICommand>("LoadCommand");
...