.NET Core 中依赖注入框架详解 Autofac
本文将通过演示一个Console应用程序和一个ASP.NET Core Web应用程序来说明依赖注入框架Autofac是如何使用的
Autofac相比.NET Core原生的注入方式提供了强大的功能,详细可以查看Autofac官方API
(1)首先看第一个例子 控制台应用(.NET Core)
通过Nuget安装两个包 => Autofac Autofac.Extensions.DependencyInjection


public static class Demo
{
public interface IAccount { }
public interface IMessage { }
public interface ITool { }
public class Base : IDisposable
{
public Base()
{
Console.WriteLine($"{GetType().Name} Created");
} public void Dispose()
{
Console.WriteLine($"{GetType().Name} Disposed");
}
}
public class Account : Base, IAccount { }
public class Message : Base, IMessage { }
public class Tool : Base, ITool { } public static void Run()
{
//.NET Core 服务集合
var serviceCollection = new ServiceCollection()
.AddTransient<IAccount, Account>()
.AddTransient<IMessage, Message>(); var containerBuilder = new ContainerBuilder();
//将服务集合添加到Autofac
containerBuilder.Populate(serviceCollection);
//通过类型注册将服务添加到Autofac
containerBuilder.RegisterType().As(); var container = containerBuilder.Build();
IServiceProvider provider = new AutofacServiceProvider(container);
Debug.Assert(provider.GetService() is Account); }
}
- 可以看到程序中 实例化一个Autofac的ContainerBuilder,通过Populate方法遍历传入的服务集合并添加到Autofac的容器中;
- RegisterType是通过类型注册将服务添加到Autofac的容器,如果RegisterType和Populate调换加载顺序,则Populate会覆盖RegisterType的服务集合;
- ContainerBuilder调用Build方法返回的是IContainer对象,该对象实现了ILifetimeScope接口;
- 在创建AutofacServiceProvider(ILifetimeScope lifetimeScope)返回的是AutofacServiceProvider实现了IServiceProvide,可以和.NET Core 的ServiceProvider一样调用GetService创建服务实例
那么使用Autofac有哪些其它优势?下面看看 属性注入和程序集注入


public static class Demo
{
public interface IAccount { }
public interface IMessage { }
public interface ITool { }
public interface ITest { public IMessage Message { get; set; } } public class Base
{
public Base()
{
Console.WriteLine($"{GetType().Name} Created");
} }
public class Account : Base, IAccount { }
public class Message : Base, IMessage { }
public class Tool : Base, ITool { }
public class Test : Base, ITest
{
public IMessage Message { get; set; }
public Test(IAccount account, ITool tool)
{
Console.WriteLine($"Ctor : Test(IAccount, ITool)");
}
} public static void Run()
{
//.NET Core 服务集合
//var serviceCollection = new ServiceCollection()
// .AddTransient<ITool, Tool>(); var containerBuilder = new ContainerBuilder();
//将服务集合添加到Autofac
//containerBuilder.Populate(serviceCollection);
//属性注入
containerBuilder.RegisterType<Test>().As<ITest>().PropertiesAutowired();
//程序集注入
containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(t => t.BaseType == typeof(Base))
.As(t => t.GetInterfaces()[0])//调用As方法,暴露服务
.InstancePerLifetimeScope();//每个生命周期作用域的组件在每个嵌套的生命周期作用域中最多只会有一个单一实例 var container = containerBuilder.Build();
IServiceProvider provider = new AutofacServiceProvider(container);
Debug.Assert(provider.GetService<IAccount>() is Account);
Debug.Assert(provider.GetService<IMessage>() is Message);
Debug.Assert(provider.GetService<ITool>() is Tool); var test = provider.GetService<ITest>();
Debug.Assert(test.Message is Message); }
- 属性注入,<code>containerBuilder.RegisterType<Test>().As<ITest>().PropertiesAutowired()</code> 通过PropertiesAutowired 反射方式
- 程序集注册,获取当前所在程序集Assembly.GetExecutingAssembly(),查找所有基类为Base的Type,调用As暴露服务,InstancePerLifetimeScope 为每个实例创建作用域的生命周期
(2)ASP.NET Core 内置DI 与 Autofac 比较


public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddTransient<IAccount, Account>();
}
内置DI 在Startup类 ConfigureServices通过AddTransient方式注册


public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory());


Startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
//services.AddTransient<IAccount, Account>();//内置DI
} public void ConfigContainer(ContainerBuilder containerBuilder)
{
//containerBuilder.RegisterType<Account>().As<IAccount>();
var assembly = Assembly.GetEntryAssembly();
containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(t => t.BaseType == typeof(Base))
.As(t => t.GetInterfaces()[0])
.InstancePerLifetimeScope(); }
Autofac 需要在Program.cs中替换 .NET Core的默认容器 UseServiceProviderFactory(new AutofacServiceProviderFactory())
在 Startup.cs 中 创建ConfigContainer方法,服务注册和 控制台应用相似;
真正在实际项目中按照以上方式注册服务会很麻烦,难以维护,可读性差;Autofac提供了一种以模块化方式进行注册
比如我们有不同的业务模块 AModule BModule...,将这些module继承 Autofac.Module 重写Load方法进行服务注册
最后在ConfigContainer中RegisterModule进行模块化注册
public class AModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
var containerBaseType = typeof(ControllerBase); builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(t => containerBaseType.IsAssignableFrom(t) && t != containerBaseType)
.PropertiesAutowired();
}
} public void ConfigContainer(ContainerBuilder containerBuilder)
{ containerBuilder.RegisterModule<AModule>(); }
.NET Core 中依赖注入框架详解 Autofac的更多相关文章
- Net Core中数据库事务隔离详解——以Dapper和Mysql为例
Net Core中数据库事务隔离详解--以Dapper和Mysql为例 事务隔离级别 准备工作 Read uncommitted 读未提交 Read committed 读取提交内容 Repeatab ...
- 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术
这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...
- java高并发系列 - 第20天:JUC中的Executor框架详解2之ExecutorCompletionService
这是java高并发系列第20篇文章. 本文内容 ExecutorCompletionService出现的背景 介绍CompletionService接口及常用的方法 介绍ExecutorComplet ...
- Unity依赖注入使用详解
写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...
- 用工厂模式解决ASP.NET Core中依赖注入的一个烦恼
这是最近在实际开发中遇到的一个问题,用 asp.net core 开发一个后端 web api ,根据指定的 key 清除 2 台 memcached 服务器上的缓存.背景是我们在进行 .net co ...
- .Net Core中依赖注入服务使用总结
一.依赖注入 引入依赖注入的目的是为了解耦和.说白了就是面向接口编程,通过调用接口的方法,而不直接实例化对象去调用.这样做的好处就是如果添加了另一个种实现类,不需要修改之前代码,只需要修改注入的地方将 ...
- SpringDI四种依赖注入方式详解
文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star!搜索关注微信公众号 [码出Offer] 领取各种学习资料! LOGO SpringDI(依赖注入) 一.DI概述 De ...
- Spring 依赖注入方式详解
平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由 ...
- AngularJS开发指南10:AngularJS依赖注入的详解
依赖注入是一种软件设计模式,用来处理代码的依赖关系. 一般来说有三种方法让函数获得它需要的依赖: 它的依赖是能被创建的,一般用new操作符就行. 能够通过全局变量查找依赖. 依赖能在需要时被导入. 前 ...
随机推荐
- java 动态规划解决最大连续子数列和
很多动态规划算法非常像数学中的递推.我们如果能找到一个合适的递推公式,就能很容易的解决问题.我们用dp[n]表示以第n个数结尾的最大连续子序列的和,这里第n个数必须在子序列中.于是存在以下递推公式: ...
- 前后端(PHP)使用AES对称加密
前端代码: // 这个是加密用的 function encrypt(text){ var key = CryptoJS.enc.Utf8.parse('1234567890654321'); //为了 ...
- Caused by: java.lang.RuntimeException: JxBrowser license check failed: No valid license found
使用jxbrower报错,原因时证书检验失败, 解决方案: 1.首先创建证书,下面是我在IDEA maven项目中创建的位置,Java项目中在src/目录下创建, META-INF/teamdev.l ...
- Net Core 重要的技术点
Net Core 重要的技术点 1.中间件概念 Asp.Net Core作为控制台应用程序启动,在Program的Main方法是入口,通过调用CreateWebHostBuilder创建WebHost ...
- sqli-labs系列——第一关
先看了一遍关于sql的一些知识点,通关sqli-labs加深下印象.之前也因为作业的原因通关过前10关,但那时候不懂得原理,跟着网上的教程做的,所以这次尝试自己思考通关. less1 尝试and1=2 ...
- SFDC 删除操作时:验证或触发后续操作的一般解决方案
删除操作比较特殊,不能通过Workflow Rule和Process Builder,Validation Rule来Check和相应做后续操作. 目前调查只有两种工具可以监听到删除操作: Apex ...
- Android控件 之 TextClock & AnalogClock(模拟时钟)
TextClock •简介 关于时间的文本显示,Android 提供了 DigitalClock 和 TextClock. DigitalClock是Android第1版本发布,功能很简单,只显示时间 ...
- python基础(六):列表的使用(下)
列表排序的三种方式 sort()方法:原地修改列表的排序方法 注 1:" 默认是升序" ,参数 reverse=True,表示将列表降序. 注 2:" 原地修改列表&qu ...
- 结对编程_stage1
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目-第一阶段 我在这个课程的目标是 从实践中学习软件工程相关知识(结构化分析和设计方法.敏捷开发方法. ...
- canvas判断点是否在路径内
应用场景 我们的项目中有个功能是,canvas上的某个图片选中后可以再这个图片上用鼠标拖拽绘制画笔线条. 当然绘制的边界要控制在图片大小范围内的,那么鼠标是可以随意动的,怎么能控制只在图片上的时候才绘 ...