2010-06-05 511 views
6

我一直在使用Unity很长一段时间,但我一直使用它与构造函数注入。为了减少我必须注入到视图模型中的类的数量(因为我的命令依赖于它们),我想我会尝试创建一个使用属性注入的概念,从而消除对大型构造函数参数列表的需求。这是场景...Unity的属性注入导致堆栈溢出

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

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,但显然我错了。

任何想法?

回答

9

这是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"); 
+0

感谢您的回答和你的链接。我认为可能是这种情况,但由于属性注入,我认为在实例化属性类时,MainViewModel应该在容器中,“循环”引用不会成为问题 - 但显然不是问题。感谢您的清理! – Adam 2010-06-07 10:46:03