6


2

ドキュメントには、Autofacはオープンジェネリックをサポートしているので、登録して解決することができます。

登録:

builder.RegisterGeneric(typeof(PassThroughFlattener <>)).As(typeof(IFlattener <>)).ContainerScoped();

解決する:

var flattener = _container.Resolve>();

上記のコードはうまく動作します。 ただし、実行時までIFlattenerに提供されている型がわからないと仮定して、私は次のようなことをしたいと思います。

オブジェクト入力= new Address(); var flattener =(IFlattener)_container.Resolve(typeof(IFlattener <>)、new TypedParameter(typeof(IFlattener <>)、input.GetType()));

これはAutoFacで可能ですか? 私はStructureMapを使って以下からアイデアを得ました:

私はこの記事で概説したのと同じ目標を達成しようとしています。

2 Answer


9


これはAutofacでも確かに可能です。 「登録時」に、これはあなたが基本的にすることです:

  1. 開いているジェネリック型を登録します(PassThroughFlattener <>)

  2. 特定のタイプを登録する(AddressFlattener)

  3. 入力オブジェクトに基づいてIFlattenerを解決するために使用できるメソッドを登録します。

「解決時」に、以下のことを行います。

  1. メソッドを解決する

  2. IFlattenerの実装を解決するために入力パラメータでメソッドを呼び出します

これは(うまくいけば)動作中のサンプルです。

var openType = typeof(IFlattener <>);

var builder = new ContainerBuilder(); builder.RegisterGeneric(typeof(PassThroughFlattener <>))。As(openType); builder.Register()。As>(); builder.Register>(context => theObject => {var concreteType = openType.MakeGenericType(theObject.GetType()); return(IFlattener)context.Resolve(concreteType、new PositionalParameter(0、theObject));}); var c = builder.Build();

var factory = c.Resolve>();

var address = new Address(); var addressService = factory(address);

Assert.That(addressService、Is.InstanceOfType(typeof(AddressFlattener)));

var anything = "その他のデータ"; var anyService = factory(anything);

Assert.That(anyService、Is.InstanceOfType(typeof(PassThroughFlattener)));


4


実行時まで型がわからない場合は、MakeGenericTypeを使用してそれを構築できます。

var addressFlattener = _container.Resolve(typeof(IFlattener <>)。MakeGenericType(typeof(Address)));