每次调用方法时创建一个对象的新实例 [英] Creating a new instance of an object each time method is called

查看:134
本文介绍了每次调用方法时创建一个对象的新实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Messenger.Default.Register<OpenWindowMessage>(this, message =>
{
    var adventurerWindowVM = SimpleIoc.Default.GetInstance<AdventurerViewModel>();
    adventurerWindowVM.Adv = message.Argument;
    var adventurerWindow = new AdventurerView() 
    {
        DataContext = adventurerWindowVM
    };
    adventurerWindow.Show();
});

这段代码非常简单;它只是打开一个新窗口并设置新窗口的DataContext.我遇到的问题是,如果我执行两次,第一个实例的内容将被覆盖并设置为第二个实例的内容,因为adventurerWindowVM是两个窗口的DataContext,并且每次此代码被覆盖时都会被覆盖.叫.我正在寻找一种防止这种情况的方法.我希望能够使用此消息打开多个窗口,并使每个窗口都是唯一的,但是到目前为止,我还没有找到一种方法来做到这一点.任何建议将不胜感激.对于模糊的标题,我深表歉意.我不确定该问题的名字. (另外,我知道这不是一种方法.该代码块将被称为什么?)

This code is fairly simple; it just opens a new window and sets the DataContext of the new window. The problem I'm having is that if I execute this twice, the content of the first instance will be overwritten and be set to that of the second since adventurerWindowVM is the DataContext of both windows and it is overwritten each time this code is called. I'm looking for a way to prevent this; I'd like to be able to open multiple windows using this message and have each of them be unique, but thus far I haven't figured out a way to do so. Any advice would be greatly appreciated. I apologize for the vague title; I was unsure of what to name this question. (Also, I know that this isn't a method. What would this block of code be called?)

更新:我使用的是MVVM Light,我的代码基于以下示例中为我提供的示例:

Update: I'm using MVVM Light and my code is based off of an example somebody provided for me in this answer: https://stackoverflow.com/a/16994523/1667020

这是我的ViewModelLocator.cs中的一些代码

Here is some code from my ViewModelLocator.cs

public ViewModelLocator()
{
    _main = new MainViewModel();

    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    SimpleIoc.Default.Register<GameViewModel>();
    SimpleIoc.Default.Register<AdventurerViewModel>();
}

推荐答案

给出了其他答案,我想我可以说这里使用的IoC容器只是来自MvvmLight的SimpleIoC,并可以在其上获得VM的新实例您每次要做的每一个GetInstance(...)都是在尝试解析VM实例时都传递一个唯一的密钥.

Having given the other answer, I guess I can say the IoC container used here is just SimpleIoC from MvvmLight and to get a new instance of the VM on every GetInstance(...) all you need to do is pass in a unique key every time when trying to resolve an instance of the VM.

因此您可以切换

var adventurerWindowVM = SimpleIoc.Default.GetInstance<AdventurerViewModel>();

var adventurerWindowVM = SimpleIoc.Default.GetInstance<AdventurerViewModel>(System.Guid.NewGuid().ToString());

但是,正如MVVMLight的作者所提及的那样此处,这些VM将被缓存,我们需要在何时删除它们不再需要.就您而言,当Window关闭时.

However as mentioned by the author of MVVMLight Here these VM's will get cached and we need to get rid of them when no longer needed. In your case probably when the Window is closed.

因此,我需要整个lambda像这样:

Thus I'd have that entire lambda something like:

Messenger.Default.Register<OpenWindowMessage>(this, message =>
{
    var uniqueKey = System.Guid.NewGuid().ToString();
    var adventurerWindowVM = SimpleIoc.Default.GetInstance<AdventurerViewModel>(uniqueKey);
    adventurerWindowVM.Adv = message.Argument;
    var adventurerWindow = new AdventurerView() 
    {
        DataContext = adventurerWindowVM
    };
    adventurerWindow.Closed += (sender, args) => SimpleIoc.Default.Unregister(uniqueKey);
    adventurerWindow.Show();
});

注意:

尽管与仅使用( new AdventurerViewModel()自己创建新VM相比,这要花3行多一点的时间),但我仍然赞成这样做,因为如果您使用IoC容器来管理VM的LifeTime,然后让它完全管理他们.不需要时不真正喜欢mix-n-match.宁可让IoC容器执行其应有的功能.

While this is somewhat longer 3 lines compared to just creating a new VM yourself with (new AdventurerViewModel()) I still favor this because if you use an IoC container to manage LifeTime of your VM's, then have it manage them completely. Don't really like mix-n-match when not needed. Rather keep the IoC Container doing what it's meant to do.

如果您需要对VM注入和生命周期管理进行更多控制,请查看更复杂的Ioc控制器,例如 Unity . SimpleIoC只是想简单地用IoC容器使您的脚湿",在这方面做得很好.

If you need more control over VM injection and Life-time management look at more sophisticated Ioc controllers such as Unity. SimpleIoC was just meant to be a simple get your feet "wet" in IoC kind of container and it does a very good job in that regard.

这篇关于每次调用方法时创建一个对象的新实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆