Unity 的属性注入导致堆栈溢出

发布于 2024-09-04 08:21:20 字数 1177 浏览 4 评论 0原文

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

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

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 中传递的命令,但显然我错了。

有什么想法吗?

I have been using Unity for quite a while but I have always used it with constructor injection. In an effort to reduce the number of classes I have to inject into my view models (as my commands rely on them) I thought I would try creating a concept that uses Property Injection and thus quash the requirement for the large constructor parameter lists. Here is the scenario...

I am creating a View Model that has Commands located on properties that use/update the hosing View Model in some way. I wish to pass the instance of the View Model into the constructors of the Commands located on the View Models properties. E.g.

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());

When I resolve the MainViewModel class I get a StackOverflow exception (if Visual Studio comes back at all). Now I would expect Unity to create an instance of the MainViewModel first then as it is basically a singleton, then look at the instance of the View Model and create the Command passing in the newly created MainViewModel, but obviously I am wrong.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅紫色的梦幻 2024-09-11 08:21:20

这是 循环引用 错误,正如它所说,这是开发人员的避免它的责任。因此,MainViewModel 对 LoadCustomersCommand 的引用是对 MainViewModel -> 的引用。堆栈溢出。

所以你唯一能做的就是

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");

This is Circular References error, and this as it said, this is developer's responsibility to avoid it. So MainViewModel references to LoadCustomersCommand wich is refferences to MainViewModel -> StackOverflow.

So the only you can do is

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

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

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

and to resolve you'll need to do the following

var mainModel = unityContainer.Resolve<MainViewModel>();
mainModel.LoadCustomersCommand =     unityContainer.Resolve<ICommand>("LoadCommand");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文