それは何であり、どこで使用されています
Object Builder(以降OBと呼びます)は、多くの依存オブジェクトを暗黙的にリンクグラフに合成するためのメカニズムです。 OBは、2005年5月に、デスクトップアプリケーションフレームワークであるCAB (またはSmartClient)と連携したオープンソースのパターンとプラクティスを備えた「複雑なプロジェクト」の偽造を通じてMicrosoftから提供されました。 基本的なCABクラスのセットは、ユーザーがエンジンオブジェクト(ユーザーコントロール、サービス、拡張ロケーションなど)を作成するときに、OBを依存性注入メカニズムとして使用します。
自分を置く方法
ここからCABをダウンロードして配置します。 インストーラーは3つのアセンブリをGACに追加します。そのうちの1つはOBです。
Object Builderの構成要素とその仕組み
基本的に、OBはいくつかのプログラミングパターンの集合です。 構造について簡単に説明します。
- ビルダー -ファサードであり、オブジェクトのビルダーのメカニズムへの入り口です。 ユーザーに構築メソッド(
BuildUp
)、破棄メソッド(TearDown
)を提供します。 Builderには、一連の戦略( Strategy )が含まれています。各戦略は、Builderのアトミックな部分です。 さらに、 Builderには、ユーザーが必要とするメソッドを使用してオブジェクトを構築するプロセスを呼び出す機能があります。これは、いわゆる 建設のポリシー。 ユーザーがオブジェクトを構築する場合、BuildUp
を呼び出し、作成されたオブジェクトのタイプをBuildUp
に渡します。 出力は、このタイプのインスタンスです。 - 戦略-OBの一部。 戦略は、オブジェクトを構築する何らかの方法を実装します。 作業中、 Builderはチェーンに沿って進み、作成されたオブジェクトに各戦略を適用します。これにより、依存オブジェクト間の関係が実現されます。 ユーザーは独自の戦略を作成し、オブジェクトを作成するプロセスをカスタマイズできます。
- ポリシー -オブジェクトを構築するためのポリシー 。 各戦略には何らかのポリシーがあります。 ポリシーは、オブジェクトの作成時に戦略(つまり、オブジェクト環境)のコンテキストを提供します。 政治は、戦略を相互にリンクするのに役立ちます。 それはかなり複雑なことですが、過去数年の高さから、マイクロソフトはOBの機能を十分に豊かにし、(通常)新しいビルドポリシーの作成は必要ありません-十分に組み込まれています。
- LocatorとLifeTimeContainer-既にビルドされた依存関係オブジェクトを取得する場所を知るために、OBは既に作成されたオブジェクトのコンテナを必要とします。 Locatorは、 LifeTimeContainerでオブジェクトを検索し、 Builderに提示してWeakReferenceを介して依存関係を挿入できる特別なクラスです。 したがって、 LifeTimeContainerはオブジェクトのライフサイクルを管理します(つまり、オブジェクトをメモリから削除する必要がある場合とそうでない場合を認識します)。
- ステージ -OBには、オブジェクトを構築するためのライフサイクルがあります。 これらはいくつかのステップです:
- 作成前(事前作成)
- 作成
- 初期化
- 初期化後
魂には例が必要です! 例として、オブジェクトを作成します
IProgramService
マイクロサービス:
interface IProgramService
{
void DoWork();
}
* This source code was highlighted with Source Code Highlighter .
そして、その実装は次のとおりです。
class ProgramService : IProgramService
{
#region IProgramService Members
public void DoWork()
{
Console .WriteLine( string .Format( "[{0}] Program Service: DoWork()" , _guid));
}
#endregion
private Guid _guid = Guid .NewGuid();
public Guid Guid
{
get { return _guid; }
}
}
* This source code was highlighted with Source Code Highlighter .
作成コードは次のようになります。
Builder builder = new Builder();
Locator locator = new Locator();
IProgramService service = builder.BuildUp<ProgramService>(locator, null , null );
service.DoWork();
* This source code was highlighted with Source Code Highlighter .
とても簡単です。
次に、依存性注入戦略を検討します。
申込み
ビルダーを作成するためのコードを見ると、重要な戦略がどのように追加されているかがわかります。
public Builder(IBuilderConfigurator<BuilderStage> configurator)
{
Strategies.AddNew<TypeMappingStrategy>(BuilderStage.PreCreation);
Strategies.AddNew<SingletonStrategy>(BuilderStage.PreCreation);
Strategies.AddNew<ConstructorReflectionStrategy>(BuilderStage.PreCreation);
Strategies.AddNew<PropertyReflectionStrategy>(BuilderStage.PreCreation);
Strategies.AddNew<MethodReflectionStrategy>(BuilderStage.PreCreation);
Strategies.AddNew<CreationStrategy>(BuilderStage.Creation);
Strategies.AddNew<PropertySetterStrategy>(BuilderStage.Initialization);
Strategies.AddNew<MethodExecutionStrategy>(BuilderStage.Initialization);
Strategies.AddNew<BuilderAwareStrategy>(BuilderStage.PostInitialization);
Policies.SetDefault<ICreationPolicy>( new DefaultCreationPolicy());
if (configurator != null )
configurator.ApplyConfiguration( this );
}
* This source code was highlighted with Source Code Highlighter .
依存関係間の関係を作成するために使用できる方法と、これらの戦略の仕組みを理解しましょう。
TypeMappingStrategy (PreCreation)-タイプ一致ポリシー。 たとえば、最後の例では、作成するタイプを明示的に示しました。 しかし、毎回どのクラスが
IProgramService
インターフェイスを実装するかを表示したくない場合はどうでしょうか?
IProgramService
を作成し、誰が特定のタイプになるのかを知りたくない場合は、プログラマーVasyaにそれを傷つけさせてください。
ITypeMappingPolicy
を作成するポリシーを使用します。 このポリシーは、インターフェイスと特定のタイプの間の対応をロケーターに伝えます。
class TypeMappingPolicy : ITypeMappingPolicy
{
#region ITypeMappingPolicy Members
public DependencyResolutionLocatorKey Map(DependencyResolutionLocatorKey incomingTypeIDPair)
{
return new DependencyResolutionLocatorKey( typeof (ProgramService), null );
}
#endregion
}
* This source code was highlighted with Source Code Highlighter .
ポリシーの登録は次の方法で行われます。
builder.Policies.Set<ITypeMappingPolicy>( new TypeMappingPolicy(), typeof (IProgramService), null );
IProgramService service = builder.BuildUp<IProgramService>(locator, null , null );
* This source code was highlighted with Source Code Highlighter .
SingletonStrategy (PreCreation)-シングルトンとしてオブジェクトを作成するための戦略。 これは、指定されたタイプの作成されたオブジェクトが一度だけ作成されることを意味します。 このタイプを作成する以降のすべての試行は、既存のオブジェクトの置換によって置き換えられます。 これを行うには、作成されるタイプを特別なキーで明示的にマークする必要があります。
DependencyResolutionLocatorKey
:
IProgramService service = builder.BuildUp<ProgramService>(locator, null , null );
DependencyResolutionLocatorKey key = new DependencyResolutionLocatorKey( typeof (ProgramService), null );
locator.Add(key, service);
IProgramService service2 = builder.BuildUp<ProgramService>(locator, null , null );
* This source code was highlighted with Source Code Highlighter .
この場合、
service
と
service2
は同じオブジェクトを指します。
ConstructorReflectionStrategy (PreCreation)- コンストラクターを介してオブジェクトを作成するための戦略。 名前はそれ自体を表しています-戦略は
[InjectionConstructor]
属性でマークされたオブジェクトのコンストラクターを選択し、
[Dependency]
属性でマークされた各パラメーターに対してロケーターを介してそれを見つけます。 次に、コンストラクターが呼び出され、そこに落ち着いたパラメーターを渡します。
[InjectionConstructor]
public ServiceConsumer([Dependency]IProgramService service)
{
_service = service;
}
* This source code was highlighted with Source Code Highlighter .
パラメーターを挿入する方法はいくつかあります。 Dependency属性のプロパティを使用して、作成するタイプを指定したり、目的のタイプが見つからない場合の動作を決定したりできます。 たとえば、新しいものを作成する(
CreateNew
)か、例外をスローします。
[InjectionConstructor]
public ServiceConsumer(
[Dependency(CreateType= typeof (ProgramService), NotPresentBehavior=NotPresentBehavior.Throw)]IProgramService service)
{
_service = service;
}
* This source code was highlighted with Source Code Highlighter .
言うまでもなく、別のオブジェクトに依存する1つのオブジェクトを作成する場合、他のオブジェクトはロケーターで解決する必要があります。
IProgramService service = builder.BuildUp<ProgramService>(locator, null , null );
DependencyResolutionLocatorKey key = new DependencyResolutionLocatorKey( typeof (IProgramService), null );
locator.Add(key, service);
ServiceConsumer consumer = builder.BuildUp<ServiceConsumer>(locator, null , null );
* This source code was highlighted with Source Code Highlighter .
CreationStrategy (Creation)は、一般的な作成戦略です。 上記の最初の例では、オブジェクトは作成戦略によって正確に構築されます。 最初に、戦略は
ICreationPolicy
を構築するためのカスタムポリシーを検索し、ポリシーが見つからない場合は、「ネイティブ」ポリシーを使用します。 ネイティブ作成ポリシーは、(リフレクションを介して)オブジェクトの最初のコンストラクターを決定し、コンストラクター内の各依存関係(パラメーター)の構築チェーンを開始するようビルダーに指示します。 次に、
Activator
を介して実行します。 この戦略の特徴は、すでに作成されたオブジェクトをそこに転送できることです。 それから、戦略は何もしません:)それは単に、
Creation
隣に
Stage
がある他の戦略に制御を移します。 もう一度最後になりますが、言い換えれば、
new()
を介してオブジェクトを作成し、それをビルダーに渡すことができます。 この場合、ビルダーはオブジェクトを作成せず、単に依存関係をオブジェクトに挿入します。
PropertyReflectionStrategy + PropertySetterStrategy (初期化)。 オブジェクトのプロパティに依存関係を挿入できる戦略(実際、意味的には、これは1つの戦略です)。 要するに、この作業-PropertyReflectionStrategyは、
[Dependency]
属性でマークされたオブジェクトのプロパティを定義し、そこに挿入する必要があるオブジェクトのタイプを認識し、この情報をリストする
IPropertySetterPolicy
ポリシーを作成します。 さらに、チェーンに続いて、 PropertySetterStrategyが動作を開始します。これにより、ポリシーが検索され、そこから挿入する必要があるプロパティが決定され、オブジェクトが解決され、適切な場所に設定されます。 ユーザーが
IPropertySetterPolicy
を使用できるように、戦略分割チップがここにあります。
[Dependency(CreateType= typeof (ProgramService),
NotPresentBehavior=NotPresentBehavior.CreateNew)]
public IProgramService ProgramService
{
set { _service = value ; }
get { return _service; }
}
* This source code was highlighted with Source Code Highlighter .
このコードは簡単に書き直すことができます。
[CreateNew]
public ProgramService ProgramService2
{
set { _service = value ; }
}
* This source code was highlighted with Source Code Highlighter .
MethodReflectionStrategy + MethodExecutionStrategy (初期化)。 本質的に、これらの2つの戦略は、
Property
依存性戦略と同型です。 のみ、プロパティを設定する代わりに、
[InjectionMethod]
属性でマークされたメソッドが呼び出されます。
[InjectionMethod]
public void DoWork([Dependency]IProgramService service)
{
service.DoWork();
}
* This source code was highlighted with Source Code Highlighter .
BuilderAwareStrategy (初期化後)。 OBには、
OnBuiltUp
、
OnTearingDown
2つのメソッドがある特別なIBuilderAwareインターフェイスがあります。 それらをクラスに実装し、オブジェクトを構築(または破棄)するときに、戦略がそれらを呼び出します。 オブジェクトを作成した直後(すべての依存関係が設定されている場合)に何かを開始する必要がある場合に非常に便利です。
#region IBuilderAware Members
public void OnBuiltUp( string id)
{
Console .WriteLine( "Built Up!" );
}
public void OnTearingDown()
{
Console .WriteLine( "Tearing down!" );
}
#endregion
* This source code was highlighted with Source Code Highlighter .
すべての「ネイティブ」OB戦略をリストしました。 エンジンでは、開発者が戦略を追加して、フレームワークの特殊な側面をリンクできるようにします。 残念ながら、OBのすべての側面を完全に分解します。たとえば、名前付きインスタンスは影響を受けません。ポリシーのトピックは完全には開発されていません。 読者は、彼が望めば、自分でそれを理解するだろうと思う:)
実際のアプリケーション、賛否両論でそれを使用する方法
答えは簡単です-インフラストラクチャの側面として。 依存性注入を意味するアーキテクチャをアプリケーションに実装する場合、OBは医師が注文したものです。 OB自体はもともと直接使用するためのものではありませんでした。 CABエンジンでは、そのメソッドは特別なコレクション-OBファサードに変わり、プログラマーの作業を大幅に促進します。
短所:決定の最大、おそらく最大のマイナスは、OBが重いことです。 それはコードを属性で
BuildUp
せます(属性なしではできません!)そして、その
BuildUp
メソッドは、あなたが知っているように、最速のものではありません。 この問題は、クラスグラフ内のリンクを最適化することで解決できます。実際、コードを最大限に分離して依存関係の数を最小限に抑えることができます。
長所:コード、オブジェクト、およびこれに続くすべての接続性が低い。 これは、単体テストのシンプルさ、およびスタンドアロン(ハンドルを設定する必要がない場合)マイクロサービスアーキテクチャなどです。
オブジェクトビルダーの将来と結論。
現在、OBは古くなっています:(はい、申し訳ありませんが、時代遅れの技術に関する記事を書きましたが、基本から始めるのは有益なようです。さらに、Microsoft Object Builder自体が何であるかを理解せずにMicrosoft Object Builder 2について話すことは困難ですマイクロソフトは、CABエンジンを最新のUnityに置き換えます。UnityApplication Blockは、待望のWPFサポートを備えた、より柔軟性の高いプラットフォームです。実際、以下の記事では、CABとは何かを説明し、徐々にUnityに切り替えます。 、ここにリンクがあります:
CAB: msdn.microsoft.com/en-us/library/aa480450.aspx
CAB: www.codeplex.com/smartclient
ユニティ: msdn.microsoft.com/en-us/library/cc468366.aspx
Unity: www.codeplex.com/unity
CABとUnityの違い: www.codeplex.com/CompositeWPF/Release/ProjectReleases.aspx?ReleaseId=16941
ご清聴ありがとうございました。