web-dev-qa-db-ja.com

Unity2つのインターフェイスを1つのシングルトンとして登録します

unityに2つの異なるインターフェースを同じインスタンスに登録するにはどうすればよいですか...現在使用しています

        _container.RegisterType<EventService, EventService>(new ContainerControlledLifetimeManager());
        _container.RegisterInstance<IEventService>(_container.Resolve<EventService>());
        _container.RegisterInstance<IEventServiceInformation>(_container.Resolve<EventService>());

これは機能しますが、見栄えがよくありません。

だから、私はあなたがアイデアを得ると思います。 EventServiceは2つのインターフェイスを実装しています。インターフェイスを解決する場合は、同じオブジェクトへの参照が必要です。

クリス

44

[2回目の編集]

Unityが登録を処理する方法に重大な変更があったため、更新されたアプローチは機能しなくなりました。 [元の答え]は再び行く方法です。 (Unityでの変更の詳細については、以下のコメントにあるリンクを参照してください。)

[編集]

XML構成を介してこれを行うための解決策は、 ここ にあります。 その答えに基づいて、私は次のように合理化されたコードのみのアプローチを提案します。

_container.RegisterType<IEventService, EventService>(new ContainerControlledLifetimeManager());
_container.RegisterType<IEventServiceInformation, EventService>(new ContainerControlledLifetimeManager());
bool singleton = ReferenceEquals(_container.Resolve<IEventService>(), _container.Resolve<IEventServiceInformation>());

このように、EventServiceクラス自体はコンテナによって公開されません。クラスは実装の詳細と見なす必要があるため、これが望ましいアプローチです。

[元の回答]

答えは少し遅れますが、トリックを行う必要があります:

_container.RegisterType<EventService>(new ContainerControlledLifetimeManager());
_container.RegisterType<IEventService, EventService>();
_container.RegisterType<IEventServiceInformation, EventService>();

bool singleton = ReferenceEquals(_container.Resolve<IEventService>(), _container.Resolve<IEventServiceInformation>());
60
Sven Künzler

アダプターのアプローチは、そのような単純なことではかさばるように見えたので、もう少し詳しく調べました。名前付きインスタンスの問題を回避するには、タイプを登録し、インターフェイスのファクトリを登録する必要があります。

 InjectionFactory factory = new InjectionFactory(x => x.Resolve<SimulationService>());
 this.Container.RegisterType<SimulationService>(new ContainerControlledLifetimeManager());
 this.Container.RegisterType<IContentProvider>("SimulationContentProvider", factory);
 this.Container.RegisterType<ISimulationService>(factory);

このようにして、依存関係がないために私の場合は不可能だった具象クラスのインスタンスを(登録時に)作成する必要はありません。

7
Console

複数のインターフェイスでシングルトンを実行する適切な方法は次のとおりです。

_container.RegisterType<EventService>(TypeLifetime.Singleton); <- This could be an instance
_container.RegisterType<IEventService, EventService>();
_container.RegisterType<IOtherEventService, EventService>();

シングルトンとそれにすべてのマッピングを個別に登録する必要があります。 Unity v6には、一度にすべてを実行するための登録方法があります。

1
ENikS

名前付きインスタンスでも機能する1つのソリューションは、アダプターパターンを使用して、シングルトンインスタンスをラップアラウンドするインターフェイスへの使い捨てアダプターを作成することです。次に、解決されたインスタンスは、ResolveAllを使用して解決された場合、常にシングルトンインスタンスイベントに転送されます。これは、IStartableなどの汎用インターフェイスを実装するサービスのヒープがある場合に役立ちます。

public class EventServiceAdapter<T> : IEventService where T : IEventService
{
    private readonly T _adapted;
    EventServiceAdapter(T adapted)
    {
        _adapted = adapted;
    }
    public string SomeMethod()
    {
         return _adapted.SomeMethod();
    }
} 

次に、登録したシングルトンタイプの周囲にインターフェイスアダプタを登録します。

_container
    .RegisterType<EventService>(new ContainerControlledLifetimeManager())
    .RegisterType<IEventService, EventServiceAdapter<EventService>>("namedEventService");

次に、任意の数のインターフェイスの背後に任意のシングルトンを隠し、ResolveとResolveAllの両方を使用して作業できます。

0
Pete Davis