all green

プログラム、アプリ作成、Web等備忘録が中心です

MessagePipeのイベント登録でRegisterMessageBrokerを使用しない形で実装する

LifetimeScope.Configure内で行うイベントの登録がどうにかならないかなと思って調べたときのメモ

SampleLifetimeScope

protected override void Configure(IContainerBuilder builder)
{
        // MessagePipeの設定
        var options = builder.RegisterMessagePipe();
        builder.RegisterMessageBroker<EventA>(options);
        builder.RegisterMessageBroker<EventB>(options);
        builder.RegisterMessageBroker<EventC>(options);
        ↑これをなんとかしたい
}

・環境
Unity 2022.3.11f1
VContainer 1.13.2
MessagePipe 1.7.4


EventA、EventB、EventCを発行するクラスが同じなので
何とかならないかなと思っていたらこんな記事を見つけました。

Pus/Subで通知が出来るってのはわかる……。
スゲーよくわかる送信と受信だからな……。
だが、Publishの条件が『型』っていうのはどういう事だぁ~~~~っ!?
いくらクラスがつくれるからってよ、intとか同じ型で別のメッセージやり取りしたい、型ごとにグループ化されていないことって沢山あるじゃねーか!!
それごとにクラスやキーを作れるかつーのよ――――ッ!
ナメやがって!!超イラつくぜェ~~~ッ!!チクショ――ッ!!
ってギアッチョ並にブチ切れた人が居るかもしれない。

orotiyamatano.hatenablog.com

イベントファクトリーを使えばいいらしい。
ひとまずこんな形にしてみました。

SampleLifetimeScope

protected override void Configure(IContainerBuilder builder)
{
    // MessagePipeの設定
    builder.RegisterMessagePipe();

    builder.Register<SampleEventProvider>(Lifetime.Singleton).AsImplementedInterfaces().AsSelf();
    builder.RegisterEntryPoint<SamplePresenter>(Lifetime.Singleton);
}

SampleEventProvider

public class SampleEventProvider: ITickable, ILateTickable, IDisposable
{
    IDisposablePublisher<EventA> eventAPublisher;
    IDisposablePublisher<EventB> eventBPublisher;
    IDisposablePublisher<EventC> eventCPublisher;

    public ISubscriber<EventA> OnEventA { get; }
    public ISubscriber<EventB> OnEventB { get; }
    public ISubscriber<EventB> OnEventC { get; }

    public SampleEventProvider(EventFactory eventFactory)
    {
        (eventAPublisher, OnEventA ) = eventFactory.CreateEvent<EventA>();
        (eventBPublisher, OnEventB ) = eventFactory.CreateEvent<EventB>();
        (eventCPublisher, OnEventC ) = eventFactory.CreateEvent<EventC>();
    }
 
   // ※破棄処理は必須、リークする
    public void Dispose()
    {
        eventAPublisher.Dispose();
        eventBPublisher.Dispose();
        eventCPublisher.Dispose();
    }
   
   // 適当な例
    public void LateTick()
    {
        if (Input.GetMouseButtonUp(0))
        {
            eventAPublisher.Publish(new EventA());        
        }      
  }
}

SamplePresenter

public class SamplePresenter: IPostInitializable
{
    SampleEventProvider sampleEventProvider;

    public SamplePresenter(SampleEventProvider sampleEventProvider)
    {
        this.sampleEventProvider = sampleEventProvider;
    }

    /// <summary>
    /// 初期化直後に呼ばれる
    /// </summary>
    public void PostInitialize()
    {
        sampleEventProvider.OnEventA.Subscribe(OnEventA);
        sampleEventProvider.OnEventB.Subscribe(OnEventB);
        sampleEventProvider.OnEventC.Subscribe(OnEventC);
    }
}

SampleEventProviderが発行するイベント3つ分すっきり。

・LifetimeScopeのRegisterMessageBrokerが無くなる
・SamplePresenterのInjectionがISubscriber3つからSampleEventProvider1つになる