赞
踩
1、IOC框架核心原理是依赖倒置原则
使用这种思想方式,可以让我们无需关心对象的生成方式,只需要告诉容器我需要的对象即可,而告诉容器我需要对象的方式就叫做DI(依赖注入)。
今天主要想研究一下DI(依赖注入),这里我选了VContainer
地址:https://github.com/hadashiA/VContainer
文档地址:https://vcontainer.hadashikick.jp/
由于我们使用的是Unity,而主要的Mono不支持构造函数。所以我们这里选择注入方式主要是特性注入和方法注入
1、注册类型
- public class GameLifetimeScope : LifetimeScope
- {
- protected override void Configure(IContainerBuilder builder)
- {
- builder.RegisterEntryPoint<ActorPresenter>();
- }
- }
2、方法注入
这里实现接口 IStartable和ITickable。它是不依赖于Mono的接口,因此性能上更好,另一方面,IStartable与Mono的Start,ITickable与Mono的Update都是相同的。
- public class ActorPresenter : IStartable,ITickable
- {
- public void Start()
- {
- Debug.Log("Start ActorPresenter");
- }
-
- public void Tick()
- {
- Debug.Log("Update ActorPresenter");
- }
- }
Model层
- public class UIModel
- {
- public void Hello()
- {
- Debug.Log("Hello World");
- }
- }
View层
- public class UIView : MonoBehaviour
- {
- public Button button;
- }
Control层
- public class UIControl : IStartable
- {
- readonly UIModel _model;
- readonly UIView _view;
-
- public UIControl(UIModel model)
- {
- this._model = model;
- }
-
- public UIControl(UIModel model, UIView view)
- {
- this._model = model;
- this._view = view;
- }
-
- public void Start()
- {
- _view.button.onClick.AddListener(() => _model.Hello());
- }
- }

通过这样做,我们成功地分离了领域控制/控制流/显示组件
在VContainter中,记得注册
- public class GameLifetimeScope : LifetimeScope
- {
- public UIView helloScreen;
- protected override void Configure(IContainerBuilder builder)
- {
- builder.RegisterEntryPoint<UIControl>();
- builder.Register<UIModel>(Lifetime.Singleton);
- builder.RegisterComponent(helloScreen);
- }
- }
构造函数里,只需要写一个需要依赖注入的函数,成员变量里就可以随时获得对象。如下例子ClassB构造函数的参数是ClassA,我们的classA变量就可以随时使用
- class ClassB : IStartable,ITickable
- {
- readonly ClassA a;
- public ClassB(ClassA a)
- {
- Debug.Log("ClassA构造函数注入");
- this.a = a;
- }
-
- public void Start()
- {
- a.Start();
- }
-
- public void Tick()
- {
- a.Update();
- }
- }

- class ClassA
- {
- public ClassA()
- {
- Debug.Log("ClassA构造");
- }
-
- public void Start()
- {
- Debug.Log("Start");
- }
- public void Update()
- {
- Debug.Log("Update");
- }
- }
-

- public class GameLifetimeScope : LifetimeScope
- {
- //public UIView helloScreen;
-
- protected override void Configure(IContainerBuilder builder)
- {
-
- builder.RegisterEntryPoint<ClassB>();
- builder.Register<ClassA>(Lifetime.Singleton);
- }
- }
- class ClassB : IStartable,ITickable
- {
- private ClassA a;
-
- [Inject]
- public void GetClassA(ClassA a)
- {
- Debug.Log("方法注入");
- this.a = a;
- }
-
- public void Start()
- {
- a.Start();
- }
-
- public void Tick()
- {
- a.Update();
- }
- }

- class ClassB : IStartable,ITickable
- {
- [Inject]
- private ClassA a;
-
- public void Start()
- {
- a.Start();
- }
-
- public void Tick()
- {
- a.Update();
- }
- }
3、注册接口
- public class GameLifetimeScople : LifetimeScope
- {
- protected override void Configure(IContainerBuilder builder)
- {
- //接口
- builder.Register<ILogger, Logger>(Lifetime.Singleton);
- builder.RegisterEntryPoint<LoggerEntryPoint>();
- }
- }
- interface ILogger
- {
- void Log(string message);
- }
-
- public class Logger : ILogger
- {
- public void Log(string message)
- {
- Debug.Log(message);
- }
- }
- public class LoggerEntryPoint : IStartable
- {
- [Inject] private ILogger logger;
- public void Start()
- {
- logger.Log("哈哈哈");
- }
- }

4、注册工厂
- public class GameLifetimeScople : LifetimeScope
- {
- protected override void Configure(IContainerBuilder builder)
- {
- //工厂
- builder.RegisterEntryPoint<LoggerEntryPoint>();
- builder.RegisterFactory<ILogger>(() => new Logger());
- }
- }
- public class Logger : ILogger
- {
- public void Log(string message)
- {
- Debug.Log(message);
- }
- }
- public class LoggerEntryPoint : IStartable
- {
- private ILogger logger;
- [Inject]
- public LoggerEntryPoint(Func<ILogger> loggerFactory)
- {
- logger = loggerFactory.Invoke();
- }
- public void Start()
- {
- logger.Log("哈哈哈");
- }
- }

带参
- public class GameLifetimeScople : LifetimeScope
- {
- protected override void Configure(IContainerBuilder builder)
- {
- //工厂
- builder.RegisterEntryPoint<LoggerEntryPoint>();
- builder.RegisterFactory<string, ILogger>((value) => new Logger(value));
- }
- }
- using VContainer.Unity;
- using VContainer;
- using UnityEngine;
- using System;
- public interface ILogger
- {
- void Log(string message);
- }
-
- public class Logger : ILogger
- {
- public Logger(string value)
- {
- Debug.Log($"实例化:{value}");
- }
- public void Log(string message)
- {
- Debug.Log(message);
- }
- }
- public class LoggerEntryPoint : IStartable
- {
- [Inject]
- public LoggerEntryPoint(Func<string, ILogger> loggerFactory)
- {
- loggerFactory.Invoke("第一个对象").Log("哈哈哈");
- loggerFactory.Invoke("第二个对象").Log("啦啦啦");
- }
-
- public void Start()
- {
-
- }
- }

4、RegisterInstance
- protected override void Configure(IContainerBuilder builder)
- {
- builder.RegisterEntryPoint<LoggerEntryPoint>();
- var logger = new Logger();
- builder.RegisterInstance(logger);
-
- }
- public interface ILogger
- {
- void Log(string message);
- }
-
- public class Logger : ILogger
- {
- public void Log(string message)
- {
- Debug.Log(message);
- }
- }
- public class LoggerEntryPoint : IStartable
- {
- public LoggerEntryPoint(Logger logger)
- {
- logger.Log("哈哈哈");
- }
-
- public void Start()
- {
-
- }
- }

5、RegisterComponent
- private TestMonoBehaviour testMonoBehaviour;
-
- protected override void Configure(IContainerBuilder builder)
- {
- testMonoBehaviour = GetComponent<TestMonoBehaviour>();
- builder.RegisterEntryPoint<LoggerEntryPoint>();
- builder.RegisterComponent(testMonoBehaviour);
- }
- public class LoggerEntryPoint : IStartable
- {
- public LoggerEntryPoint(TestMonoBehaviour testMonoBehaviour)
- {
- testMonoBehaviour.Log("11111111");
- }
-
- public void Start()
- {
-
- }
- }
6、不依赖EntryPoint
- builder.Register<Logger>(Lifetime.Singleton);
- builder.RegisterBuildCallback(objectResolver =>
- {
- objectResolver.Resolve<Logger>();
- });
- public class Logger
- {
- public Logger()
- {
- Debug.Log("hahhah");
- }
- }
如果经常这样使用,可以拓展
- 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<Logger>();
- public class Logger
- {
- public Logger()
- {
- Debug.Log("啦啦啦");
- }
- }
如果有此扩展方法,则可以使用一行调用与以前相同的 Register 和 RegisterBuildCallback。builder.RegisterPlainEntryPoint<EntryPointSample>();
7、处理EntryPoint的异常情况
- builder.RegisterEntryPointExceptionHandler(e =>
- {
- Debug.LogException(e);
- });
生命周期:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。