0

MVVMパターンと単純なServiceLocator実装を使用していますが、問題が発生した場合、ビューが設計時に実行されているときにサービスをどのようにセットアップする必要がありますか?

Ivはこれを試しましたが、VS 2010などでは機能しないようです。古いコンピューターでは機能することはわかっていますが、新しいコンピューターでは機能しません。それで、誰かが良い代替案を知っていますか?

編集:(マーリン・モーガン・グラハムに代わって)

私がやろうとしているのはこれです。私の見解、ViewModel、およびサービスがあります。ここでの違いは、各サービスの2つの実装が設計時と実行時用にあることです。より良い説明については、こちらをご覧ください。

4

3 に答える 3

1

ビューをビューモデルから切り離し、ビューモデルをモデル/ダルから切り離したい場合(基本的に、MVVMを使用したい場合)、ビューモデルとデータモデルは設計時間について何も知らないはずです。設計時間はビューにのみ適用されます。

この記事では、XML / XAMLを介して設計時データを定義する方法を示しているため、その下のコードはそれについて何も知る必要はありません。

http://karlshifflett.wordpress.com/2009/10/21/visual-studio-2010-beta2-sample-data-project-templates/

編集後:既存のXAMLバインディングを機能させるには、ビューモデルを使用する必要があることがわかります。これにより、新しいデータモデルを作成するのではなく、ビューモデルにデータが入力されます。よくわかりませんが、WPFバインディングメカニズムを使用してこれを処理できるクラスがある可能性があります...ビュー?

編集前に再開...:最初にリンクした記事のソリューションに関する限り、デザイナーはクラスとそれが参照するコード以外はインスタンス化しません。つまり、ビューコードが何らかの方法で直接参照しない限り、アセンブリ属性はインスタンス化されません。

設計時にビューモデルをビューに結合し、設計時サービスが登録されるようにする場合は、サービス登録コードをビュークラス、またはビュークラスが直接参照するクラスに配置する必要があります。

これを行うには、ビューの静的コンストラクターを使用して、デザインタイムサービスを登録できます。他のクラス(アプリケーション?)に静的メソッドを記述して、(条件付きで)設計時サービスを登録することもできます。次に、ビューのコンストラクターでそのメソッドを呼び出します。

または、ビューごとにコンストラクターに登録することもできます。

基本的にあなたがやりたいことは可能ですが、最初の記事でリンクされているその方法はそうではありません。コメントをさらに読むと、彼の方法が壊れていることがわかります。

MVVMパターンはそのようなことを避けるために作成されたため、設計時にビューモデルをビューにフックするというアイデアに疑問を呈することもできます。

于 2010-08-16T03:02:58.247 に答える
0

通常、設計時にサービスにアクセスする必要はありません...通常、設計時に実際のViewModelを使用することもなく、ここで説明するように、ダミーの設計データを使用します。実際のViewModelを実際に使用する必要がある場合は、サービスのダミーバージョンを実装し、実際のサービスの代わりにそれらを使用できます。

if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
    // Design time
    ServiceLocator.Instance.Register<IService1>(new DummyService1());
    ServiceLocator.Instance.Register<IService2>(new DummyService2());
}
else
{
    // Run time
    ServiceLocator.Instance.Register<IService1>(new RealService1());
    ServiceLocator.Instance.Register<IService2>(new RealService2());
}
于 2010-08-15T21:25:23.843 に答える
0

また、設計時にサービスロケーターの使用について懸念を持っているすべての人に同意します。これは、一部のユースケースでは有効なシナリオであると信じています。これはなぜ/なぜそうではないかについての議論ではありません、これはそれが(ほとんど)私のために働いた方法で簡単です。私がまだ解決していない問題がまだあります。これは一度に1つのビューに対してのみ機能します。

  1. 選択したIoCを設定するための単純なブートストラッパーを作成します。ISupportInitializeインターフェースに注目してください。

    public class Bootstrapper: ISupportInitialize
    {
        #region ISupportInitialize Members
    
        public void BeginInit() { }
    
        public void EndInit()
        {
            if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
                Setup();
        }
    
        #endregion
    
        public static void Setup() { SetupServiceLocator(); }
    
        static void SetupServiceLocator()
        {
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<ConfigService>().As<IConfigService>().ExternallyOwned().SingleInstance();
            IContainer container = builder.Build();
    
            ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container));
        }
    }
    
  2. ランタイムモードでは、以前と同じようにBootstrapperを使用します。例:

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Bootstrapper.Setup();
        }
    }
    
  3. さらに、デザインモードをサポートするためにアプリケーションリソースに追加する必要があります。

    <Application x:Class="MonitoringConfigurator.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:MyBootstrapperNamespace"
                 StartupUri="MainWindow.xaml">
        <Application.Resources>
            <local:Bootstrapper x:Key="Bootstrapper" />
        </Application.Resources>
    </Application>
    
于 2014-12-03T14:03:40.383 に答える