1

全て -

DI 用の WPF アプリケーションで Unity を使用しています (プリズムなし)。MainWindow.xaml と MainWindowViewModel.cs があります。Mainwindow.xaml にユーザー コントロールがあります。ユーザー コントロールには、独自の uc1.xaml と uc1viewmodel.cs があります。UC1 ViewModel は現在、MainWindowViewModel のプロパティとして公開されているため、ユーザー コントロールにデータ コンテキストを設定できます (ここで多くの ppl が推奨するように)。

私が持っている質問は、このプロパティをどのように/どこで設定できるかです-それは app.xaml.cs にあるのでしょうか、それとも mainwindowviewmodel のコンストラクターにありますか? コード スニペット:

App.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. 
    }
}

MainWindow.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) で作成されるため、MainWindow インスタンスが app.xaml.cs で作成されても、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 が null の場合、またはアプリケーションが開始など...)。

App.xaml で

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

そして今、データコンテキストを設定できます

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

編集:

私はそれを行う別の方法を(とりわけ)見つけました:この記事を見てください。コマンドでは、ビューモデルを好きなように解決できます。

于 2013-09-05T07:35:01.017 に答える