一、IOC控制反转和DI依赖倒置
1、IOC框架核心原理是依赖倒置原则
C#设计模式的六大原则
使用这种思想方式,可以让我们无需关心对象的生成方式,只需要告诉容器我需要的对象即可,而告诉容器我需要对象的方式就叫做DI(依赖注入)。
今天主要想研究一下DI(依赖注入),这里我选了VContainer
地址:https://github.com/hadashiA/VContainer
文档地址:https://vcontainer.hadashikick.jp/
二、VContainer介绍
由于我们使用的是Unity,而主要的Mono不支持构造函数。所以我们这里选择注入方式主要是特性注入和方法注入
三、VContainer案例
(1)简单方法注入:
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");
}
}
(2)基础MVC功能:
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);
}
}
(3)构造注入
构造函数里,只需要写一个需要依赖注入的函数,成员变量里就可以随时获得对象。如下例子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);
}
}
(4)方法注入(其他的和上边一样)
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();
}
}
(5)字段/属性注入
class ClassB : IStartable,ITickable
{
[Inject]
private ClassA a;
public void Start()
{
a.Start();
}
public void Tick()
{
a.Update();
}
}