ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

.NET依赖注入[32]

2021-05-29 19:29:54  阅读:208  来源: 互联网

标签:容器 Autofac 依赖 映射 32 SauceB arnaise 类型 NET


Autofac DI容器

在本章中

  • 使用Autofac的基本注册API工作
  • 管理组件的寿命
  • 配置复杂的API
  • 配置序列、装饰器和组合物

  在前几章中,我们讨论了适用于一般DI的模式和原则,但是,除了几个例子之外,我们还没有详细研究如何使用任何特定的DI容器来应用它们。在本章中,你将看到这些总体模式如何映射到Autofac。你需要熟悉前几章的材料,才能从中充分受益。
  Autofac是一个相当全面的DI容器,提供了一个精心设计和一致的API。它从2007年末开始存在,在撰写本文时,它是最受欢迎的容器之一。
  在本章中,我们将研究如何利用Autofac来应用第1-3部分中提出的原则和模式。本章分为四个部分。你可以独立地阅读每一节,尽管第一节是其他章节的前提,第四节依赖于第三节中介绍的一些方法和类。
  这一章应该能让你开始使用,以及处理你在日常使用Autofac时可能出现的最常见的问题。这并不是对Autofac的完整处理;这需要更多的章节,或者本身就是一本书。如果你想了解更多关于Autofac的信息,最好从Autofac的主页开始,网址是https://autofac.org。

13.1 介绍Autofac

  在本节中,你将了解从哪里获得Autofac,你得到什么,以及如何开始使用它。我们还将看一下常见的配置选项。表13.1提供了你可能需要的基本信息,以便开始使用。

表13.1 Autofac概览

问题答案
我在哪里可以得到它?从Visual Studio,你可以通过NuGet获得它。包的名称是Autofac。另外,NuGet包也可以从GitHub仓库(https://github.com/autofac/Autofac/releases)下载。
哪些平台受到支持?.NET 4.5(无.NET Core SDK)和.NET标准1.1(.NET Core 1.0、Mono 4.6、Xamarin.iOS 10.0、Xamarin.Mac 3.0、Xamarin.Android 7.0、UWP 10.0、Win-dows 8.0、Windows Phone 8.1)。支持.NET 2.0和Silver-light的较早版本可以通过NuGet历史记录获得。
它的费用是多少?没有。它是开源的
它是如何获得许可的?MIT License.
我在哪里可以得到帮助?你可以从与Autofac开发商有关的公司获得商业支持。请在https://autofac.readthedocs.io/en/latest/support.html 上阅读更多关于这些选择。除了商业支持,Autofac仍然是开源软件,有一个繁荣的生态系统,所以你也有可能(但不能保证)通过在Stack Overflow上发帖(https://stackoverflow.com)或使用官方论坛(https://groups.google.com/group/autofac)获得帮助。
本章是基于哪个版本?4.9.0-beta1
--------

  使用Autofac与使用我们将在下面几章讨论的其他DI容器没有什么不同。 如同Simple Injector和Microsoft.Extensions .DependencyInjection,使用是一个两步的过程,如图13.1所示。首先,你配置一个 ContainerBuilder,当你完成配置后,你用它来构建一个容器来解决组件。

图13.1 使用Autofac的模式是首先配置它,然后再解决组件。

 
  当你看完这一节后,你应该对Autofac的整体使用模式有一个很好的感觉,你应该能够开始在良好的场景中使用它–所有的组件都遵循正确的DI模式,比如构造函数注入。让我们从最简单的场景开始,看看你如何使用Autofac容器来解析对象。

13.1.1 解决对象

  任何DI容器的核心服务都是对对象图进行组合。 在这一节中,我们将看一下让你用Autofac组合对象图的API。
  默认情况下,Autofac要求您在解决这些问题之前注册所有相关组件。然而,这种行为是可以配置的。下面的列表显示了Autofac的一个最简单的可能用途。

清单13.1 Autofac的最简单使用方法

var builder = new ContainerBuilder();
builder.RegisterType < SauceBéarnaise > ();
IContainer container = builder.Build();
ILifetimeScope scope = container.BeginLifetimeScope();
SauceBéarnaise sauce = scope.Resolve < SauceBéarnaise > ();

  如图13.1所示,你需要一个ContainerBuilder实例来配置组件。在这里,你用builder注册具体的SauceBéarnaise类,这样当你要求它建立一个容器时,产生的容器就会被配置成SauceBéarnaise类。这又使你能够从容器中解析SauceBéarnaise类。
  然而,在 Autofac 中,你永远不会从根容器本身解析,而是从生命周期范围解析。第 13.2.1 节详细介绍了生命周期范围,以及为什么从根容器解析是一件坏事。

警告 在Autofac中,直接从根容器中进行解析是一种不好的做法。这很容易导致内存泄漏或并发错误。相反,你应该总是从一个生命周期的范围来解析。

  如果你没有注册SauceBéarnaise组件,试图解决它就会抛出一个ComponentNotRegisteredException,信息如下。

The requested service “Ploeh.Samples.MenuModel.SauceBéarnaise” has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

  Autofac不仅可以用无参数构造函数解决具体的类型,还可以将一个类型与其他依赖自动连接起来。所有这些依赖都需要被注册。在大多数情况下,你会希望对接口进行编程,因为这引入了松耦合。为了支持这一点,Autofac允许你将抽象映射到具体类型。

将抽象概念映射到具体类型
  而你的应用程序的根类型通常由它们的具体类型来解决,松耦合要求你将抽象映射到具体类型。基于这种映射创建实例是任何DI容器所提供的核心服务,但你仍然必须定义映射。在这个例子中,你将IIngredient接口映射到具体的SauceBéarnaise类,这使你能够成功地解析IIngredient。

var builder = new ContainerBuilder();
//将一个具体的类型映射到一个抽象中
builder.RegisterType < SauceBéarnaise > ().As < IIngredient > ();
IContainer container = builder.Build();
ILifetimeScope scope = container.BeginLifetimeScope();
//解决了SauceBéarnaise类
IIngredient sauce = scope.Resolve < IIngredient > ();

  As方法允许一个具体类型被映射到一个特定的抽象。由于之前的As()调用,SauceBéarnaise现在可以被解析为IIngredient。
  你使用ContainerBuilder实例来注册类型和定义映射。 RegisterType方法让你注册一个具体的类型。
  正如你在清单13.1中看到的,如果你只想注册SauceBéarnaise类,你可以在这里停止。你也可以继续使用As方法来定义应该如何注册具体类型。

警告 与Simple Injector和Microsoft.Extensions.DependencyInjection相反,RegisterType和As方法定义的类型之间没有通用类型约束。这意味着有可能映射不兼容的类型。代码会被编译,但在运行时,当 ContainerBuilder 构建容器时,你会得到一个异常。

  在许多情况下,通用的API就是你所需要的全部。 尽管它不像其他一些 DI 容器那样提供相同程度的类型安全,但它仍然是配置容器的一种可读的方式。 不过,在有些情况下,你需要一种更弱类型的方式来解决服务。有了Autofac,这也是可能的。

解决弱类型的服务
  有时你不能使用通用API,因为你在设计时不知道适当的类型。你所拥有的只是一个Type实例,但你还是想获得该类型的实例。你在第7.3节看到了一个例子,我们在那里讨论了ASP.NET Core MVC的IControllerActivator类。相关的方法是这样的。

object Create(ControllerContext context);

  如之前listing 7.8所示,ControllerContext捕获了控制器的类型,你可以使用ActionDescriptor属性的ControllerTypeInfo属性来提取它。

Type controllerType = context.ActionDescriptor.ControllerTypeInfo.AsType();

  因为你只有一个Type实例,所以你不能使用通用的Resolve方法,而必须求助于弱类型的API。Autofac提供了一个弱类型的Resolve方法的重载,让你像这样实现Create方法。

Type controllerType = context.ActionDescriptor.ControllerTypeInfo.AsType();return scope.Resolve(controllerType);

  Resolve的弱类型重载允许你直接将controllerType变量传递给Autofac。通常情况下,这意味着你必须将返回的值转换为某个抽象概念,因为弱类型的Resolve方法返回对象。然而,在IControllerActivator的情况下,这并不是必须的,因为ASP.NET Core MVC并不要求控制器实现任何接口或基类。
  无论你使用哪种Resolve的重载,Autofac都能保证它能返回一个请求类型的实例,或者在有依赖不能满足的情况下抛出一个异常。 当所有需要的依赖都被正确配置后,Autofac可以自动连接所请求的类型。
  在前面的例子中,范围是Autofac.ILifetimeScope的一个实例。为了能够解决所请求的类型,所有松耦合的依赖必须事先配置好。有很多方法可以配置Autofac,下一节将回顾最常见的方法。

标签:容器,Autofac,依赖,映射,32,SauceB,arnaise,类型,NET
来源: https://blog.csdn.net/u013716859/article/details/117388636

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有