6

問題

DryIoc を使用してシングルトンを登録しようとしていますが、コンテナーがシングルトン クラスの複数のインスタンスを返しています。singleton クラスは、複数の異なるサービス インターフェイスの実装タイプとして登録されます。前述のサービス インターフェイスのいずれかが DryIoc から要求された場合、シングルトン クラスの同じインスタンスが返されることを期待していますが、そうはならず、その理由がわかりません。

これが私がやろうとしていることの基本的な例です。この例では、インターフェイスおよびFooのシングルトン実装として使用したいクラスがあります。つまり、またはがコンテナから解決されたときに、 の同じインスタンスが返されるようにしたいと考えています。IFooIBarIFooIBarFoo

サービス インターフェイス

interface IFoo
{   
}
interface IBar
{   
}

シングルトン (実装) クラス

class Foo : IFoo, IBar
{
}

テスト

Container container = new Container();
container.Register<IFoo, Foo>(Reuse.Singleton);
container.Register<IBar, Foo>(Reuse.Singleton);

object foo = container.Resolve<IFoo>();
object bar = container.Resolve<IBar>();
Assert.AreSame(foo, bar); // Why does this fail?

考えられる解決策

DryIoc のRegisterInstanceメソッドを使用することを検討しましたが、それにはクラスを手動で作成する必要があり、上記の単純化された例とは異なり、実際のクラスには独自の依存関係があるため、それを回避しようとしています。

4

2 に答える 2

9

このRegisterメソッドは、個別/独立した登録をコンテナーに追加します。複数のサービスに同じ登録を使用するように具体的に言う必要があります。

オプション 1: RegisterMany

// registers with Foo interfaces and itself. Remove @nonPublicServiceTypes to restrict for public types
container.RegisterMany<Foo>(Reuse.Singleton, nonPublicServiceTypes: true);

Assert.AreSame(container.Resolve<IFoo>(), container.Resolve<IBar>());

オプション 2: RegisterMapping

container.Register<IFoo, Foo>(Reuse.Singleton);
container.RegisterMapping<IBar, IFoo>(); // maps to the IBar registration

Assert.AreSame(container.Resolve<IFoo>(), container.Resolve<IBar>());

他の:

@Fyodorの回答のように、解決を手動で委任します。

于 2016-08-30T05:37:17.923 に答える
3

DryIoc の「再利用」の概念は、実装ではなくサービスに適用されます。登録は 2 つの異なるサービス (IFooおよびIBar) に対するものであるため、それらは異なる再利用を取得します。また、実装 ( ) を共有するという事実はFooここでは当てはまりません。

目標を達成するためmadeに、実装へのリダイレクトを介してサービスを登録できます。

container.Register<Foo>( Reuse.Singleton );
container.Register<IFoo, Foo>( made: Made.Of( () => ReturnThis( Arg.Of<Foo>() ) ), reuse: Reuse.Singleton );
container.Register<IBar, Foo>( made: Made.Of( () => ReturnThis( Arg.Of<Foo>() ) ), reuse: Reuse.Singleton );

// Where ReturnThis is define thusly:
static T ReturnThis<T>( T t ) => t;

ReturnThis(ネイキッドMade.Of( () => Arg.Of<Foo>() )は機能しないため、呼び出しが必要です。Made常にメソッド呼び出しが必要です)

于 2016-08-30T02:34:02.987 に答える