14
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VContainer入門(5) - EntryPoint

Last updated at Posted at 2021-09-07

この記事について

前回に引き続きVContainerの説明をしていきます。

今回はEntryPointについて説明します。
EntryPointを使うとMonoBehaviourを継承しないクラスでもUpdateなどのイベントを利用できます。

目次ページ: VContainer入門

EntryPointを使ってみる

EntryPointとして使うクラスでは用意されたインターフェースを実装します。
次の例ではITickableインターフェースを実装したTickableSampleクラスを用意しています。

TickableSample.cs
public sealed class TickableSample : ITickable
{
    // このメソッドがUpdateのタイミングで呼び出される
    public void Tick()
    {
        Debug.Log("Tick : " + Time.time);
    }
}

ITickableはTickメソッドが定義されているだけのインターフェースです。
このクラスをRegisterEntryPointで登録すると使えます。

LifetimeScope
protected override void Configure(IContainerBuilder builder)
{
    builder.RegisterEntryPoint<TickableSample>();
}

これでTickableSampleのTickがUpdateのタイミングで呼び出されるようになります。

エントリーポイントの登録(RegisterEntryPoint)

RegisterEntryPointで登録されたクラスは、IContainerBuilderの生成直後にインスタンス化されます。
Registerで登録されたクラスは、他クラスからの依存関係を解決するタイミングでインスタンス化される点で異なります。

つまり、RegisterEntryPointで登録すれば他から依存されていなくても必ずインスタンス化されるエントリーポイントとして利用できます。

登録できるインターフェースの一覧

ITickableはUpdateのタイミングで呼び出されますが、Update以外で呼び出されるインターフェースも使えます。
以下のインターフェースが使えます。

インターフェース メソッド 呼び出されるタイミング
IInitializable Initialize() クラスが生成された直後
IPostInitializable PostInitialize() IInitializableが呼び出された直後
IStartable Start() MonoBehaviourのStartの直前
IPostStartable PostStart() MonoBehaviourのStartの直後
ITickable Tick() MonoBehaviourのUpdateの直前
IPostTickable PostTick() MonoBehaviourのUpdateの直後
IFixedTickable FixedTick() MonoBehaviourのUpdateの直前
IPostFixedTickable PostFixedTick() MonoBehaviourのUpdateの直後
ILateTickable LateTick() MonoBehaviourのLateUpdateの直前
IPostLateTickable PostLateTick() MonoBehaviourのLateUpdateの直後

RegisterEntryPointに渡すクラスは上記のインターフェースを1つ以上実装する必要があります。
どのインターフェースも実装されていないクラスを渡しても、そのクラスはインスタンス化されません。

また、そのクラスにIDisposableが実装されていればIObjectResolverが破棄されるタイミングでDisposeが呼び出されます。

エントリーポイントの生成

前述の通り、RegisterEntryPointで登録してインスタンス化してもらうにはいずれかのインターフェースが必要です。

インターフェースで提供されるイベントが必要ないクラスでも、VContainerにインスタンス化してほしい時には次の手段があります。

  • 実際には使わないIInitializableを実装しておく
  • RegisterBuildCallbackを利用する

以下でそれぞれ説明します。

使わないIInitializableを実装しておく

こちらは単純に、とりあえずIInitializableを実装しておくだけです。

EntryPointSample.cs
public sealed class EntryPointSample : IInitializable
{
    public void Initialize()
    {
        // 何もしない
    }
}

このクラスをRegisterEntryPointで登録すれば、不要なInitialize呼び出しは発生しますがインスタンスは生成されます。

RegisterBuildCallbackを利用する

こちらではVContainerのEntryPointの機能に頼らず、RegisterBuildCallbackで強制的にインスタンスを生成してしまいます。

EntryPointSample.cs
public sealed class EntryPointSample
{
}
LifetimeScope
protected override void Configure(IContainerBuilder builder)
{
    builder.Register<EntryPointSample>(Lifetime.Singleton);

    builder.RegisterBuildCallback(objectResolver =>
    {
        objectResolver.Resolve<EntryPointSample>();
    });
}

RegisterBuildCallbackを使うと、IObjectResolverの生成直後に呼び出されるコールバックを登録できます。
そのコールバックの中でobjectResolver.Resolveを呼び出してインスタンスを生成させています。

こちらの方法を多用する際は、RegisterとRegisterBuildCalbackを行う拡張メソッドを用意しておくと便利です。

ObjectResolverExtensions.cs
public static class ObjectResolverExtensions
{
    public static RegistrationBuilder RegisterPlainEntryPoint<T>(this IContainerBuilder builder, Lifetime lifetime = Lifetime.Singleton)
    {
        builder.RegisterBuildCallback(objectResolver => objectResolver.Resolve<T>());
        return builder.Register<T>(lifetime);
    }
}

この拡張メソッドを用意しておけば、builder.RegisterPlainEntryPoint<EntryPointSample>();の一行で先ほどと同じRegisterとRegisterBuildCallbackを呼び出せます。

例外処理(RegisterEntryPointExceptionHandler)

RegisterEntryPointExceptionHandlerで、EntryPoint内で発生した例外を処理できます。

TickableSample.cs
public sealed class TickableSample : ITickable
{
    public void Tick()
    {
        throw new System.NotImplementedException();
    }
}
LifetimeScope
protected override void Configure(IContainerBuilder builder)
{
    // 例外が発生したときに呼び出されるコールバックを登録できる
    builder.RegisterEntryPointExceptionHandler(e =>
    {
        Debug.LogException(e);
    });

    builder.RegisterEntryPoint<TickableSample>();
}

RegisterEntryPointExceptionHandlerを使わない場合、発生した例外はDebug.LogExceptionで出力されます。
なので上記のサンプルコードのRegisterEntryPointExceptionHandlerはデフォルトの動作と同じになります。

14
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?