依赖注入容器Unity的使用指南

如果是直接访问本部分的,可能会发现代码难以理解。因此,在开始阅读本文之前,请先阅读前面的部分。为了方便导航到之前的文章,提供了以下链接:

  • 第1部分:依赖倒置原则
  • 第2部分:控制反转与IoC容器
  • 第3部分:自定义IoC容器
  • 第4部分:具有生命周期选项的自定义IoC容器
  • 第5部分:使用Microsoft Unity进行依赖注入(当前阅读)

概述
Unity容器(Unity)是一个功能齐全、可扩展的依赖注入容器。它有助于构建松散耦合的应用程序,并为开发人员提供以下优势:

  • 简化对象创建,特别是对于层次结构的对象和依赖
  • 抽象需求;这允许开发人员在运行时或配置中指定依赖,并简化跨关注点的管理
  • 通过将组件配置推迟到容器,增加了灵活性
  • 服务定位能力;这允许客户端存储或缓存容器
  • 实例和类型拦截
  • 按约定注册

依赖注册
注册依赖可以让IoC容器知道依赖的具体实现。例如,如果想要在请求解析IReader依赖时获得KeyboardReader的实例,需要注册依赖IReader,它解析KeyboardReader类的实例。以下是使用Unity容器进行依赖注册的示例。 C# IUnityContainer container = new UnityContainer(); container.RegisterType(); 通过上述注册,在解析类型IReader时,将返回KeyboardReader的实例。

Unity容器支持以下方式进行依赖注册:

  • 实例注册
  • 工厂注册
  • 类型注册

实例注册
通过实例注册,告诉IoC容器,当有人请求解析依赖时,将返回注册的实例。实例注册在想要以特定状态注册依赖的情况下很有帮助。RegisterInstance()方法用于在容器中注册一个实例。 C# var keyboardReader = new KeyboardReader(); container.RegisterInstance(keyboardReader); 通过上述注册,在解析类型KeyboardReader时,将返回注册的实例。

实例可以在IoC容器中使用名称注册。以下是示例: C# var keyboardReaderA = new KeyboardReader(); var keyboardReaderB = new KeyboardReader(); container.RegisterInstance("InstanceA", keyboardReaderA); container.RegisterInstance("InstanceB", keyboardReaderB); 通过上述注册,在解析类型KeyboardReader时,需要提供名称,因为没有不带名称的注册存在。因此,在上述情况下,使用container.Resolve(KeyboardReader, "InstanceA")解析类型KeyboardReader将返回keyboardReaderA实例,而使用container.Resolve(KeyboardReader, "InstanceB")将返回keyboardReaderB实例。

实例注册还支持类型映射。这意味着可以针对类型(类或接口)注册一个实例,以便在解析类型时,将返回注册的实例给调用者。以下是示例: C# var keyboardReader = new KeyboardReader(); container.RegisterInstance(keyboardReader); 通过上述注册,在解析类型KeyboardReader时,将返回注册的keyboardReader实例。

工厂注册
使用工厂注册,可以根据函数调用的输出注册依赖。它在注册实例时提供了更多的控制。 C# var keyboardReader = new KeyboardReader(); container.RegisterFactory(fn => new KeyboardReader());

类型注册
类型注册是广泛使用的注册类型。在这种类型的注册中,需要提供契约类型和具体类型,解析契约类型将产生具体类型的实例。类型注册的最低要求是类型本身。以下是一个注册示例: C# container.RegisterType(); 通过上述注册,在解析类型KeyboardReader时,将返回KeyboardReader的实例。

以下是另一个注册示例,可以提供契约类型及其具体类型。 C# container.RegisterType(); // 默认注册 通过上述注册,在解析类型KeyboardReader时,将返回KeyboardReader的实例。

还可以在注册类型时提供名称: C# container.RegisterType("Keyboard"); 通过上述注册来解析依赖,需要使用container.Resolve("Keyboard")。

注意:名称的默认值是null。当在没有传递任何名称的情况下注册类型时,这种注册被称为默认注册。

示例应用程序
让使用Visual Studio创建一个控制台应用程序。在这个演示应用程序中,使用了Visual Studio 2019。但可以使用任何版本的Visual Studio(从Visual Studio 2012开始)。 右键单击项目,然后单击“管理NuGet程序包...”。管理NuGet程序包用于向应用程序添加第三方库。 在管理NuGet程序包窗口中,选择“浏览”选项,搜索Unity并安装程序包。在撰写本文时,Unity的最新版本是5.11.6。但可以使用任何稳定版本进行演示应用程序。 在Program.cs文件中添加以下代码行: C# using System; using Unity; namespace ConsoleApp { class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.RegisterType(); var reader = container.Resolve(); var readText = reader.Read(); Console.WriteLine($"The output is : {readText}"); Console.ReadLine(); } } interface IReader { string Read(); } class KeyboardRader : IReader { public string Read() { return "Reading from keyboard..."; } } }

示例应用程序已准备好运行。按F5运行控制台应用程序。 将获得以下输出: 如所见,使用类型注册将类型IReader注册为KeyboardReader具体类型。因此,当尝试解析类型IReader时,将获得KeyboardReader的实例。调用Read()方法将返回"Reading from keyboard...",这将在控制台上打印出来。

Unity容器提供了许多其他功能,将在下一篇文章中介绍。同时,将向展示注入依赖的不同方式。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485