美文网首页zenJect
Zenject框架(八)

Zenject框架(八)

作者: 虫小白 | 来源:发表于2019-03-13 10:44 被阅读0次

    场景绑定(Scene Bindings)

    在许多情况下,你有很多MonoBehaviour已经被添加到Unity编辑器的场景中(在编辑时而不是运行时),并且你想要将这些MonoBehaviour添加到Zenject容器中,以便它们可以被注入其他类。
    这样做的通常方法是在安装器中添加对这些对象的公共引用,如下所示:

    public class Foo : MonoBehaviour
    {
    }
    
    public class GameInstaller : MonoInstaller
    {
        public Foo foo;
    
        public override void InstallBindings()
        {
            Container.BindInstance(foo);
            Container.Bind<IInitializable>().To<GameRunner>().AsSingle();
        }
    }
    
    public class GameRunner : IInitializable
    {
        readonly Foo _foo;
    
        public GameRunner(Foo foo)
        {
            _foo = foo;
        }
    
        public void Initialize()
        {
            ...
        }
    }
    

    这种方法可以,但在某些情况下,这可能会很麻烦。例如,允许向场景添加任意数量的Enemy对象,并且还希望将所有这些Enemy对象添加到Zenject容器中。在这种情况下,您必须手动拖动每个对象到安装器的检视面板中。这很容易出错,因为它很容易忘记,或者删除Enemy游戏对象后却忘记在检查面板删除安装器的空引用等。
    另一种方法是使用FromComponentInHierarchy绑定方法,如下所示:

    public class GameInstaller : MonoInstaller
    {
        public override void InstallBindings()
        {
            Container.Bind<Foo>().FromComponentInHierarchy().AsTransient();
            Container.Bind<IInitializable>().To<GameRunner>().AsSingle();
        }
    }
    

    现在,每当需要类型为Foo的依赖项时,zenject将在整个场景中搜索任何类型为Foo的MonoBehaviours。每次要查找某个特定类型依赖项时都以这种方式进行,这与Unity的FindObjectsOfType方法非常相似。请注意,因为此方法是一个非常繁重的操作,所以最好将其标记为AsCached或AsSingle:

    public class GameInstaller : MonoInstaller
    {
        public override void InstallBindings()
        {
            Container.Bind<Foo>().FromComponentInHierarchy().AsCached();
            Container.Bind<IInitializable>().To<GameRunner>().AsSingle();
        }
    }
    

    这样,查找过程只会在第一次需要的时候进行,而不是每次注入都会进行。注意,需要查找多个Foo类型时,可以使用FromComponentsInHierarchy(注意这儿是复数形式)

    另一种方法是使用ZenjectBinding组件。您可以通过将ZenjectBinding组件添加到要自动添加到Zenject容器的同一游戏对象来完成此操作。

    例如,在场景中有一个Foo类型的MonoBehaviour ,则只需将ZenjectBinding组件添加到同一个物体上,然后将Foo组件拖动到ZenjectBinding组件的Component属性中。


    然后,安装器改为:
    public class GameInstaller : MonoInstaller
    {
        public override void InstallBindings()
        {
            Container.Bind<IInitializable>().To<GameRunner>().AsSingle();
        }
    }
    

    ZenjectBinding组件具有以下属性:

    • Bind Type-我们在这里确定要使用的“ contract type ”。它可以设置为以下任何值:

    * Self
    这相当于我们这样做的第一个例子:

    Container.Bind<Foo>().FromInstance(_foo);
    

    等价地:

    Container.BindInstance(_foo);
    

    因此,如果我们复制这个游戏对象以便得到多个包含Foo组件(还有ZenjectBinding组件)的游戏对象,它们都将以这种方式绑定到容器上。因此,在执行此操作之后,我们需要将上面GameRunner的参数改为List<Foo>否则将抛出Zenject异常(有关列表绑定的信息,请参阅后续“List Bindings”章节)。
    * AllInterfaces
    此绑定类型等效于以下内容:

    Container.BindInterfacesTo(_foo.GetType()).FromInstance(_foo);
    

    注意,这种这种情况下,GameRunner的构造函数的参数类型必须是IFoo类型,如果是Foo类型,zenject将会抛出异常,因为BindInterfaces方法只能绑定接口而不能绑定具体的类型,如果你需要绑定具体的类型,你可以使用:

    * AllInterfacesAndSelf
    此绑定类型等效于以下内容:

    Container.BindInterfacesAndSelfTo(_foo.GetType()).FromInstance(_foo);
    

    这种方式与AllInterfaces类似,但除了绑定接口外,还可以直接绑定具体的类

    * BaseType
    此绑定类型等效于以下内容:

    Container.Bind(_foo.GetType().BaseType()).FromInstance(_foo)
    
    • Identifier - 此值可以在大多数时间保留为空。它将确定用作绑定标识符的内容。例如,当设置为“Foo1”时,它相当于执行以下操作:
    Container.BindInstance(_foo).WithId("Foo1");
    
    • Use Scene Context- 这是可选的,但在您希望将GameObjectContext内的依赖项绑定到SceneContext的情况下非常有用。您也可以将SceneContext正确拖动到Context,但这个标志更容易一些。

    • Context -这是完全可选的,在大多数情况下应该保留未设置状态。这将决定Context应用绑定的内容。如果未设置,它将使用游戏对象所处的任何上下文。在大多数情况下都是SceneContext,但如果它处于GameObjectContext中,它将被绑定到GameObjectContext的容器上。此字段的一个重要用例是当组件处于GameObjectContext中时,允许将SceneContext拖动到此字段中。这允许您将此MonoBehaviour视为GameObjectContext提供的整个子容器的Facade(参考外观模式)。

    相关文章

      网友评论

        本文标题:Zenject框架(八)

        本文链接:https://www.haomeiwen.com/subject/jnqzpqtx.html