注册组件

通过容器构造器ContainerBuilder注册组件的三种方式:

  1. 通过类型反射注册

  2. 通过现存实例注册(实现对象的实例)

  3. lambda表达式注册(通过可实例化对象的匿名函数注册)

每个组件可暴露一个或多个服务,通过ContainerBuilder中的As()方法组装

// 创建注册组件/服务的构建器。
var builder = new ContainerBuilder();

// 通过类型反射注册
builder.RegisterType<ConsoleLogger>().As<ILogger>();

// 通过实例对象注册
var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();

// 通过创建实例对象的lambda表达式注册
builder.Register(c => new ConfigReader("mysection")).As<IConfigReader>();
// 通过容器构造器ContainerBuilder创建容器
// 准备对象解析
var container = builder.Build();

// 你现在可以通过 Autofac去解析服务.比如,
//此行代码将解析并获取(执行注册的lambda表达式注册的那个)服务的依赖实例reader

using(var scope = container.BeginLifetimeScope())
{
var reader = scope.Resolve<IConfigReader>();
}

反射组件

按类型注册

通过反射生成的组件通常按类型注册

//创建容器生成器
var builder = new ContainerBuilder();
//通过反射注册的两种写法
builder.RegisterType<ConsoleLogger>();
builder.RegisterType(typeof(ConfigReader));

当使用基于反射的组件时,Autofac 会自动为您的类使用构造函数,其中包含能够从容器中获取的最多参数

例如,假设您有一个包含三个构造函数的类,如下所示:

public class MyComponent
{
public MyComponent() { Console.WriteLine("无参构造方法被调用"); }
public MyComponent(InterfaceTestA testA) { Console.WriteLine("第一个方法A被调用"); }
public MyComponent(InterfaceTestA testA, InterfaceTestB testB) { Console.WriteLine("方法A、B都被调用"); }
public void test()
{
Console.WriteLine("方法Test被调用");
}
}
 

现在假设您在容器中注册组件和服务,如下所示:

 static void Main(string[] args)
{
var build = new ContainerBuilder();
build.RegisterType<EntityImpA>().As<InterfaceTestA>();
build.RegisterType<EntityImpB>().As<InterfaceTestB>();
build.RegisterType<MyComponent>();
Console.WriteLine("Hello World!");
var containner = build.Build();
using (var scope = containner.BeginLifetimeScope())
{
//用生命周期作用域解析获取IDateWriter对应的依赖对象实例
var writer = scope.Resolve<MyComponent>();
writer.test();
}
}

当您解析您的组件cope.Resolve<MyComponent>()时,Autofac 将看到您已EntityImpA、EntityImpB注册,在这种情况下,将选择第三个构造函数

public MyComponent(InterfaceTestA testA, InterfaceTestB testB) { Console.WriteLine("方法A、B都被调用"); }

假设您在容器中注册组件和服务,如下所示:

 static void Main(string[] args)
{
var build = new ContainerBuilder();
build.RegisterType<EntityImpA>().As<InterfaceTestA>();
//build.RegisterType<EntityImpB>().As<InterfaceTestB>();
build.RegisterType<MyComponent>();
Console.WriteLine("Hello World!");
var containner = build.Build();
using (var scope = containner.BeginLifetimeScope())
{
//用生命周期作用域解析获取IDateWriter对应的依赖对象实例
var writer = scope.Resolve<MyComponent>();
writer.test();
}
}

当您解析您的组件cope.Resolve<MyComponent>()时,Autofac 将看到您已EntityImpA注册,EntityImpB没注册在这种情况下,将选择第二个构造函数

public MyComponent(InterfaceTestA testA) { Console.WriteLine("第一个方法A被调用");因为它是容器中可以找到的参数最多的构造函数。

基于反射的组件的重要说明:您注册的任何组件类型都RegisterType必须是具体类型

指定构造函数

也可以通过一个特定的构造函数来使用和重写这种自动选择的构造方法,通过UsingConstructor方法和一系列表示构造函数中参数类型的参数列表注册你的组件

builder.RegisterType<MyComponent>()
      .UsingConstructor(typeof(ILogger), typeof(IConfigReader));

请注意,您仍需要在解析时提供必要的参数,否则在尝试解析对象时会出现错误。您可以在注册时传递参数,也可以在解析时传递参数。

此时解析时会走的构造方法是public MyComponent(ILogger logger, IConfigReader reader) { /* ... */ }

AUTOFAC学习DEMO2-——ContainerBuilder注册三种方式、反射注册的更多相关文章

  1. 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比

    [原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...

  2. PHP的学习--连接MySQL的三种方式

    记录一下PHP连接MySQL的三种方式. 先mock一下数据,可以执行一下sql. /*创建数据库*/ CREATE DATABASE IF NOT EXISTS `test`; /*选择数据库*/ ...

  3. AngularJs学习——实现数据绑定的三种方式

    三种方式: 方式一:<h5>{{msg}}</h5>  此方式在页面刷新的时候会闪现{{}} 方式二:<h5 ng-bind="msg">< ...

  4. Spring学习(二)三种方式的依赖注入

    1.前言 上一篇讲到第一个Spring项目的创建.以及bean的注入.当然.注入的方式一共有三种.本文将展开细说. 1.set注入:本质是通过set方法赋值 1.创建老师类和课程类 1.Course ...

  5. 【Android学习】数据传递三种方式

    1.Application 注意在清单文件中的Application节点下注册android:name属性, 继承Application类,重写onCreate方法, 使用数据时,实例化自定义类时需要 ...

  6. Ioc容器Autofac系列(3)-- 三种注册组件的方式

    简单来说,所谓注册组件,就是注册类并映射为接口,然后根据接口获取对应类,Autofac将被注册的类称为组件. 虽然可像上篇提到的一次性注册程序集中所有类,但AutoFac使用最多的还是单个注册.这种注 ...

  7. 注册Jdbc驱动程序的三种方式

    注册Jdbc驱动程序的三种方式 1. Class.forName("com.mysql.jdbc.Driver"); 2. DriverManager.registerDriver ...

  8. ios网络学习------4 UIWebView的加载本地数据的三种方式

    ios网络学习------4 UIWebView的加载本地数据的三种方式 分类: IOS2014-06-27 12:56 959人阅读 评论(0) 收藏 举报 UIWebView是IOS内置的浏览器, ...

  9. java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService

    前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...

  10. JDBC注册驱动的三种方式

    JDBC注册驱动的三种方式 1.通过导入的JDBC的驱动包拿到的com.mysql.jdbc.Driver对象,利用java.sql.DriverManager对象的DriverManager.reg ...

随机推荐

  1. 喜讯!天翼云斩获NLP国际顶会比赛两项荣誉

    近日,NLP国际顶会ACL(The Association for Computational Linguistics)进行的国际赛事WASSA 2023(13th Workshop on Compu ...

  2. StarUML画流程图

    一.新建流程图 1.1 新建流程图 1.2 左侧操作符介绍 Flow:顾名思义就是流,用来从一个操作流向下一个操作. Process: 过程 Terminator:用在结束的时候. Dicision: ...

  3. 多节点oceanbase 集群部署

    安装前准备 硬件要求 CPU最少2核 磁盘最少19G 文件系统EXT4 戓 XFS 关闭透明大页 echo never > /sys/kernel/mm/redhat_transparent_h ...

  4. JUC并发—9.并发安全集合二

    大纲 1.并发安全的数组列表CopyOnWriteArrayList 2.并发安全的链表队列ConcurrentLinkedQueue 3.并发编程中的阻塞队列概述 4.JUC的各种阻塞队列介绍 5. ...

  5. 【Unity】光照解决方案笔记

    [Unity]光照解决方案笔记 https://docs.unity.cn/cn/2022.3/Manual/BestPracticeLightingPipelines.html 确定对象显示效果的三 ...

  6. P5355 [Ynoi Easy Round 2017] 由乃的玉米田

    莫队 + bitset + 根号分支 乘法似乎是简单的,我们可以直接莫队扫描然后枚举较小数 时间 \((n + m) \sqrt n\). 加法是一个经典 idea, 莫队套 bitset,然后利用 ...

  7. ITSS 运维-服务台相关内容

  8. 【P5】Verilog搭建流水线MIPS-CPU

    课下 Thinking_Log 1.为何不允许直接转发功能部件的输出 直接转发会使一些组合逻辑部件增加新的长短不一的操作延迟,不利于计算设置流水线是时钟频率(保证流水线吞吐量?). 2.jal中将NP ...

  9. python3 报错ModuleNotFoundError: No module named 'apt_pkg'

    前言 apt update无法执行,python3 报错 ModuleNotFoundError: No module named 'apt_pkg' 这是因为将 python 版本升级后的问题 正确 ...

  10. mac上zsh环境变量如何配置

    环境变量配置 在 macOS 上,如果你使用的是 zsh 作为默认的 shell,那么 /bin/zsh 的环境变量通常可以在以下文件中配置: ~/.zshrc ~/.zprofile ~/.zshe ...