@atomarasは抽象化について良い点を持っているかもしれませんが、構成ルート内でこの情報のみを使用する場合は問題ないと思います。構成ルートはシステム内のすべての実装をすでに認識しているためです。
この情報にアクセスする方法はいくつかあると思います。
使用
DecoratorPredicateContext
に提供される情報RegisterDecorator
拡張方法:var typeMapping = new Dictionary<Type, Type>(); container.RegisterDecorator(typeof(IInstructionHandler<>), typeof(FakeDecorator<>), c => { typeMapping[c.ServiceType] = c.ImplementationType; // or perhaps even use c.AppliedDecorators property to see which decorators // are applied. // return false to prevent the decorator from being applied. return false; });
簡単なインジェクターがすべてを呼び出すという偽の登録を行うことができます
IInstructionHandler<T>
システム内では、常に戻ってくる述語を提供することによってそれが適用されるのを防ぎますfalse
. 。単純なインジェクターが提供する情報を使用することができますDecoratorPredicateContext
実際の実装タイプが何であるかを確認します。
または、ANを注入することもできます DecoratorContext
インスタンス(v2.6以降)が最も多くのデコレーターに(説明されているように) ここ)。 DecoratorContext
と同じ情報が含まれています DecoratorPredicateContext
そうですが、このオブジェクトは、単純なインジェクターによって自動的に注入されます。これにより、デコレーター内で決定を下すことができます。これは、あなたの場合に非常に便利かもしれません。
anを追加します
IDecorator
システムへの抽象化により、デコレーターチェーンを横断することができます。各デコレーターにaを実装させることにより
IDecorator
decoreeeへのアクセスを可能にするインターフェイス(完了したとおり ここ)デコレーターチェーンを通過して、実際の実装タイプを見つけることができます。public interface IDecorator { object Decoratee { get; } } public static class DecoratorHelpers { public static IEnumerable<object> GetDecoratorChain(IDecorator decorator) { while (decorator != null) { yield return decorator; decorator = decorator.Decoratee as IDecorator; } } }
次のように、このインターフェイスでデコレーターを実装できます。
public class SomeDecorator<T> : IInstructionHandler<T>, IDecorator { private readonly IInstructionHandler<T> decoratee; public SomeDecorator(IInstructionHandler<T> decoratee) { this.decoratee = decoratee; } object IDecorator.Decoratee { get { return this.decoratee; } } }
すべてのデコレーターにこのインターフェイスを実装すると、これを行うことができます。
var implementationTypes = from handler in container.GetAllInstances<IInstructionHandler<RenderWord>>() let mostInnerDecorator = DecoratorHelpers.GetDecoratorChain(handler as IDecorator).LastOrDefault() let implementation = mostInnerDecorator != null ? mostInnerDecorator.Decoratee : handler select implementation.GetType()
のリストを登録します
Registration
の1つのインスタンスRegisterAll
以来Registration
オブジェクトは、実際の実装タイプを知っています。ただし、ポイント3の代わりに、それらの登録を作成するために使用したインプレメーションタイプのリストを使用することもできます。
typeMapping[serviceType] = implementationTypes; container.RegisterAll(serviceType, implementationTypes);
単純なインジェクターは、登録された実装を常に登録しているのと同じ順序で解決します(これが保証されます)。したがって、物事のコレクションを解決すると、同じ順序でレイアウトされた実装のリストが既にあります。