1

全部 -

我在我的 DI 的 WPF 应用程序中使用 Unity(没有棱镜)。我有我的 MainWindow.xaml 和 MainWindowViewModel.cs。我的 Mainwindow.xaml 中有一个用户控件。用户控件有自己的 uc1.xaml 和 uc1viewmodel.cs。UC1 ViewModel 当前作为 MainWindowViewModel 上的属性公开,因此我可以在用户控件上设置数据上下文(如许多 ppl 推荐的那样)。

我的问题是如何/在哪里可以设置此属性 - 它是在 app.xaml.cs 中还是在 mainwindowviewmodel 的构造函数中。代码片段:

应用程序.xaml.cs

protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        //Step 1 - One Time - Creating an instance of the container
        UnityContainer unity = new UnityContainer();

        //Step 2 - Registering your MainWindowViewModel
        unity.RegisterType<IViewModel, UserControl1ViewModel>();

        //Step 3 - Creating an Instance
        UserControl1ViewModel uc1_mwvm = unity.Resolve<UserControl1ViewModel>();  <-- doesnt help
        MainWindowViewModel mwvm = unity.Resolve<MainWindowViewModel>();

        MainWindow mw = unity.Resolve<MainWindow>();

        mw.Show();
    }

MainWindowViewModel.cs

public class MainWindowViewModel
{
    public IViewModel IVM { get; set; }

    public MainWindowViewModel()
    {
        //IVM = new UserControl1ViewModel(); <-- All I really want is an equivalent but letting Unity do the work. 
    }
}

主窗口.xaml

<Window x:Class="_05_ViewFist_UC_Unity_Working.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:uc1="clr-namespace:_05_ViewFist_UC_Unity_Working"
     xmlns:uc2="clr-namespace:_05_ViewFist_UC_Unity_Working"
    Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Vertical">
    <TextBlock Text="{Binding NNN}" />
    <uc1:UC1 DataContext="{Binding UC1VM}" />
    <uc2:UC2 DataContext="{Binding UC2VM}" />
</StackPanel>
</Window>

UC1

<UserControl x:Class="_05_ViewFist_UC_Unity_Working.UC1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" >
<StackPanel Orientation="Horizontal" Background="Red">
    <TextBlock Text="UC1 "  />
    <TextBlock Text="{Binding FirstName}"  />
</StackPanel>
</UserControl>

正如您从代码中看到的 - UC1 的实例是在 xaml (MainWindow.xaml) 中创建的,因此当在 app.xaml.cs 中创建 MainWindow 实例时 - 它仍然不会创建 UserControl1ViewModel 的实例。

再次问题是:不要认为我在 MainwindowViewModel 的构造函数中调用 Unity Resolve 语句是一个好习惯。那是对的吗??

有人可以分享我如何/在哪里可以做到这一点的代码片段吗?

谢谢

4

2 回答 2

1

我从 github 下载了您的解决方案并尝试解决您的问题。

您做得很好,只是您忘记了一些细节,例如属性属性。

这就是您的 App.cs 文件的外观:

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        //Step 1 - One Time - Creating an instance of the container
        UnityContainer unity = new UnityContainer();

        //Step 2 - Registeration
        unity.RegisterType<IMainWindowViewModel, MainWindowViewModel>();
        unity.RegisterType<IUC1ViewModel, UC1ViewModel>();
        unity.RegisterType<IUC2ViewModel, UC2ViewModel>();


        //// Instance of MainWindowViewModel will be created once you call Resolve MainWindow.


        MainWindow mw = unity.Resolve<MainWindow>();

        mw.Show();
    }

这是我所做的更改:

public class MainWindowViewModel : IMainWindowViewModel
{
    #region Public Properties

    [Dependency]
    public IUC1ViewModel UC1VM { get; set; }

    [Dependency]
    public IUC2ViewModel UC2VM { get; set; }

    public string NNN { get; set; }

    #endregion

    public MainWindowViewModel()
    {
        NNN = "This value coming from MainWindowViewModel";
    }
}

[Dependency]是一个属性属性,它告诉 Unity 在哪里注入值。

如果您愿意,我可以将我的代码合并到您在 github 中的存储库中。

让我知道这是否对您有任何帮助。随意将其标记为答案。

于 2013-09-20T20:42:23.343 回答
1

您可以使用服务定位器模式。我将它与 Unity 一起用作 DI。

internal class ServiceLocator
{
    [...]
    public MainViewModel Main { get { return container.Resolve<MainViewModel>(); } }
}

您可以按照您想要的方式实例化您的类(DI 与否,该类初始化 DI 或将其作为参数接收,您可以将 DI 存储在私有静态属性中,如果 DI 为空或应用程序时,您可以初始化您的类开始等...)。

在您的 App.xaml

<Application.Resources>
        <vm:ServiceLocator x:Key="Locator"/>
    </Application.Resources>

现在,您可以设置数据上下文

DataContext="{Binding Main, Source={StaticResource Locator}}"

编辑:

我找到了另一种方法(除其他外):看看这篇文章。在命令中,您可以根据需要解析视图模型。

于 2013-09-05T07:35:01.017 回答