漫坊亭

社会の底辺プログラマ

(自分用翻訳) Caliburn.Micro > Documentation > Customizing The Bootstrapper

原文へのリンク (google翻訳)

Customizing The Bootstrapper

最後の部分では、Caliburn.Microための最も基本的な構成について議論し、アクションと規則に関連する単純な機能のいくつかを明らかにしました。この部分では、私は少しより多くのブートストラップクラスを探索したいと思います。のは、IoCコンテナを使用するように私たちのアプリケーションを構成することから始めましょう。私たちは、この例ではMEFを使用しますが、Caliburn.Microはどのコンテナでうまく動作します。まず、先に行くと、私たちは私たちの出発点としてそれを使用しようとしているパート1からのコードをつかみます。 System.ComponentModel.CompositionとSystem.ComponentModel.Composition.Initialization:二つの追加の参照を追加します。それらは今、MEFのfunctionality.1が含まれているアセンブリをしている、のはMefBootstrapperと呼ばれる新しいブートストラップを作成してみましょう。次のコードを使用します。

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Linq;

public class MefBootstrapper : BootstrapperBase
{
    private CompositionContainer container;

    public MefBootstrapper()
    {
        Start();
    }

    protected override void Configure()
    {
        container = CompositionHost.Initialize(
            new AggregateCatalog(
                    AssemblySource.Instance
                    .Select(x => new AssemblyCatalog(x))
                    .OfType<ComposablePartCatalog>()
                )
            );

        var batch = new CompositionBatch();

        batch.AddExportedValue<IWindowManager>(new WindowManager());
        batch.AddExportedValue<IEventAggregator>(new EventAggregator());
        batch.AddExportedValue(container);

        container.Compose(batch);
    }

    protected override object GetInstance(Type serviceType, string key)
    {
        string contract = string.IsNullOrEmpty(key) 
                        ? AttributedModelServices.GetContractName(serviceType) : key;
        var exports = container.GetExportedValues<object>(contract);

        if (exports.Any())
            return exports.First();

        throw new Exception(
            string.Format("Could not locate any instances of contract {0}.", contract));
    }

    protected override IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return container.GetExportedValues<object>(
                   AttributedModelServices.GetContractName(serviceType));
    }

    protected override void BuildUp(object instance)
    {
        container.SatisfyImportsOnce(instance);
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        DisplayRootViewFor<IShell>();
    }
}

それはMEFを統合するためのすべてのコードです。まず、ブートストラップクラスの設定メソッドをオーバーライドします。これが私たちのIoCコンテナを設定するだけでなく、我々はそのようなカスタマイズ慣習として、やりたいことがあり、他のフレームワークの構成を実行する機会を与えてくれます。この場合、私はセットアップCompositionContainerにシルバーのCompositionHostの利点を取っています。あなたが.NETを使用している場合は、あなただけの直接の容器をインスタンス化することができます。そして、私はAggregateCatalogを作成し、AssemblyCatalogsでそれを移入です。 AssemblySource.Instanceの各アセンブリのための1つ。だから、AssemblySoure.Instanceは何ですか?これはCaliburn.Microはビューを探します場所です。あなたは、フレームワークで利用できるようにするアプリケーションの中にいつでもこれにアセンブリを追加することができますが、ブートストラップでそれを行うための特別な場所もあります。単にこのようなSelectAssembliesをオーバーライドします。

protected override IEnumerable<Assembly> SelectAssemblies()
{
    return new[] {
        Assembly.GetExecutingAssembly()
    };
}

あなたがしなければならないのは、検索のアセンブリのリストを返すです。デフォルトでは、基本クラスは、アプリケーションが中に存在するアセンブリを返します。すべてのあなたの意見は、アプリケーションと同じアセンブリ内にあるのであれば、あなたも、このことを心配する必要はありません。あなたはビューを含む複数の参照アセンブリを持っている場合、これはあなたが覚えておく必要がある拡張ポイントです。あなたが動的にモジュールをロードする場合にも、あなたは彼らが読み込まれたとき、彼らはあなたのIoCコンテナとAssemblySoure.Instanceに登録得ることを確認する必要があります。

コンテナを作成し、カタログでそれを提供した後、私はいくつかのCaliburn.Micro固有のサービスを追加してください。フレームワークはIWindowManagerとIEventAggregator両方のデフォルトの実装を提供します。それらは私が他の場所で依存のかかりそうだ作品ですので、私は彼らが注入のために使用できるようにしたいです。また、私は自分自身とのコンテナ(単に個人的な好み)を登録します。

我々は、コンテナを設定した後、私たちはどのようにそれを使用するCaliburn.Microに指示する必要があります。それは、以下の3オーバーライドの目的です。 「GetInstance」と「GetAllInstances」は、フレームワークによって必要とされます。「BuildUp」は、必要に応じてフレームワークによって実行されるIResultのインスタンスへの依存性を供給するために使用されます。

Word to the Wise

Caliburn.MicroはブートストラップのオーバーライドとIoCのクラスを介してのServiceLocator機能を提供しますが、あなたはあなたのアプリケーションコードでこれを直接使用することは避けてください。ServiceLocatorは、アンチパターンであることを多くの人に考えられています。コンテナから引っ張ると、依存コードの意図を曖昧にし、より複雑なテストを行うことができます傾向があります。今後の記事で私はあなたのViewModelからのServiceLocatorにアクセスするように誘惑することができる少なくとも1つのシナリオを紹介します。私はまた、いくつかの解決方法を説明します。

上に示しているものの他に、ブートストラップの他のいくつかの注目すべき方法があります。あなたは、アプリケーションの起動やは、具体的に、アプリケーションのコードで処理されなかった例外の後のクリーンアップには、それぞれとOnUnhandledExceptionシャットダウン時にコードを実行するOnStartupとフォーカス喪失時をオーバーライドすることができます。最後のオーバーライド、DisplayRootViewは、ユニークです。のは、見てみましょう、それがブートストラップで実装する方法

protected override void DisplayRootView() 
{
    var viewModel = IoC.Get<TRootModel>();
#if SILVERLIGHT
    var view = ViewLocator.LocateForModel(viewModel, null, null);
    ViewModelBinder.Bind(viewModel, view, null);

    var activator = viewModel as IActivate;
    if (activator != null)
        activator.Activate();

    Application.RootVisual = view;
#else
    IWindowManager windowManager;

    try
    {
        windowManager = IoC.Get<IWindowManager>();
    }
    catch
    {
        windowManager = new WindowManager();
    }

    windowManager.Show(viewModel);
#endif
}

この方法のSilverlightのバージョンは、コンテナからルートVMを解決するそれのためにビューを検索し、2つを一緒に結合します。それはそれは、適切なインタフェースを実装する場合、VMを「活性化」することを確認します。 WPFのバージョンは、多かれ少なかれ、ウィンドウマネージャクラスを使用して同じことを行います。 DisplayRootViewは、基本的にはモデル·ファースト開発のための便利な実装です。あなたはビューファーストMVVMを好むかもしれませんので、それを好きではない場合、これはあなたがその動作を変更するためにオーバーライドするメソッドです。

V1.1では、DisplayRootViewオーバーライドを削除し、それがDisplayRootViewForという名前のヘルパー·メソッドで機能だ置きました。一般的なブートストラップは今OnStartupオーバーライドからこのメソッドを呼び出します。 、この動作を変更するだけでOnStartupオーバーライドし、代わりに基本実装を呼び出すので、独自のアクティベーションコードを書き込みます。これは、スプラッシュ画面、ログイン画面や起動時のパラメータにアクセスするためのより良いサポートを提供します。

今、あなたはすべてのブートストラップについて理解することは、私たちのサンプル作業を取得しましょう。我々はIShellインタフェースを追加する必要があります。我々の場合には、それだけでマーカーインタフェースです。しかし、実際のアプリケーションでは、この契約を焼きいくつかの重要なシェル関連の機能を有することになります。ここでは、コードは次のとおりです。

public interface IShell
{
}

今、私たちは、インタフェースを実装し、適切なMEFの属性を持つ私たちのShellViewModelを飾るために必要があります。

[Export(typeof(IShell))]
public class ShellViewModel : PropertyChangedBase, IShell
{
   ...implementation is same as before...
}

最後に、あなたのApp.xamlを更新しMefBootstrapperにHelloBootstrapperを変更してください。それでおしまい!あなたのアップとMEFで実行していて、あなたにもブートストラップの他の主要な拡張ポイントのいくつかのハンドルを持っています。

Using Caliburn.Micro in Office and WinForms Applications

Caliburn.Micro非XAMLホストから使用することができます。アプリケーションがApp.xaml経由で開始しませんので、これを達成するために、あなたは、わずかに異なる手順を実行する必要があります。その代わりに、BoostrapperBaseから継承したカスタムboostrapper(非ジェネリック版)を作成します。あなたが継承するときは、基本コンストラクタの「useApplication」パラメータを「false」に渡す必要があります。これは、ブートストラップが正しくXAMLアプリケーションのインスタンスが存在しないCaliburn.Microを設定することができます。あなたはフレームワークを開始するためにやらなければならないことは、start()メソッドをあなたのブートストラップのインスタンスを作成して呼び出すです。クラスがインスタンス化されたら、新しいUIを表示するために、おそらくによってIWindowManagerを呼び出し、通常のようにCaliburn.Microを使用することができます。

Referenced Samples

  • Caliburn.Micro.HelloMef