我已经使用Unity已有一段时间了,但是我一直将其与构造函数注入(inject)一起使用。为了减少我必须注入(inject)到 View 模型中的类的数量(因为命令依赖它们),我认为我会尝试创建一个使用属性注入(inject)的概念,从而消除对大型构造函数参数列表的需求。这是场景...

我正在创建一个 View 模型,该模型具有位于以某种方式使用/更新管道 View 模型的属性上的命令。我希望将 View 模型的实例传递到位于 View 模型属性上的命令的构造函数中。例如。

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的实例,然后基本上是一个单例,然后查看View Model的实例并创建传入新创建的MainViewModel的Command,但是显然我错了。

有任何想法吗?

最佳答案

这是Circular References错误,正如它所说的那样,这是开发人员应避免的错误。因此,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");

10-08 17:29