C# 贪婪构造与依赖注入

C# 贪婪构造与依赖注入,c#,.net,wpf,mvvm,C#,.net,Wpf,Mvvm,对于我正在从事的一个项目,我决定采用MVVM模式 我的viewmodel需要启动许多不同的对话框,这些对话框不仅仅只是显示OK或Cancel按钮。大多数对话框都有一个列表视图,可以从中选择项目 为了保持viewmodel“无外观”,我在viewmodel构造函数中注入了不同的对话框作为接口 public ContractsData(IWindow ProjectSelector, IWindow ContractSelector, IWindow DebtorSelector) {

对于我正在从事的一个项目,我决定采用MVVM模式

我的viewmodel需要启动许多不同的对话框,这些对话框不仅仅只是显示OK或Cancel按钮。大多数对话框都有一个列表视图,可以从中选择项目

为了保持viewmodel“无外观”,我在viewmodel构造函数中注入了不同的对话框作为接口

public ContractsData(IWindow ProjectSelector, IWindow ContractSelector, IWindow DebtorSelector)
    {
        //.....
        //.....
        m_ProjectSelector = ProjectSelector;
        m_ContractSelector = ContractSelector;
        m_DebtorSelector = DebtorSelector;
    }
IWindow是:

public interface IWindow
{
    void Close();
    bool? ShowDialog();
    void SetOwner(object window);
    bool? DialogResult { get; set; }
    object DataContext { get; set; }
}
无论从测试角度将数据从视图中分离出来有多好,在构建viewmodel时,所有可能需要的对话框窗口都必须存在并完全构建,这与我的原则之一“惰性初始化”背道而驰:只在需要时构建对象。 随着我的viewmodel的发展,它可能需要一大堆对话框,这些对话框都是预先创建的,并在需要之前一直保存在内存中,这很可能永远不会发生


我曾考虑用轻量级的“工厂”对象替换实际的对话框,这些对象根据视图的请求构造对话框,但我正在寻找更好的解决方案来解决依赖项注入的内存问题。

如果使用依赖项注入容器,它们中的大多数将具有要注入的功能。因此,您可以依赖于
Lazy
,而不是
IWindow
。没有任何特殊注册,他们很聪明地为你注射


如果您使用的是穷人的注入,您可以手动构造
Lazy
并注入它。否则是另一个不错的选择。

我不知道懒惰模板。我将尝试一下。依赖注入Func是我见过的另一种方式。@code4life实际上等同于注入我在回答中提到的抽象工厂。是的,我们也可以使用
Func
。许多DI容器都是免费的。这些复杂的对话框是我们的简单对话框吗?只要所有的合并字典都在无错误的情况下被解析,并且对话框没有任何绑定错误,即使使用惰性VM构造,对话框也应该很快加载。我不确定您使用的是哪个mvvm,因此我不知道您是如何处理视图到视图模型的关系的,这样可能会对我的观察结果造成一些影响。对话框类似于Listview的ItemsSource和SelectedItem属性在viewmodel中共享。它们还共享OnOK和OnCancel命令。除此之外,它们非常不同。My viewmodel实现INotifyPropertyChanged,并用作主窗口和对话框的数据上下文。我不确定是否建议在不同的ListView之间共享ItemsSource属性。如果您发现自己在构建时面临性能问题,那么懒散地构建它们将是一个非常好的主意-构件做得太多是DI中的一个经典问题。在这方面,通过尽你所能的懒惰来推迟成本在不同程度上有所帮助。不确定您将保留多少内存。我通常更喜欢实证指标,这意味着拿出我的ants分析器来获得一个清晰的想法。从我的角度来看,跟踪内存消耗对于每个新项目来说都是一个不同的故事。这不是MVVM,即使你正在抽象UI,所以不管你想做什么,都去做吧。此模式更像MVC,其中ViewModel实际上是控制器。但不管怎么做。