IOC模式和依赖注入是近年来非常流行的一种模式,相信大家都不陌生了,在Asp.Net Core中提供了依赖注入作为内置的基础设施,如果仍不熟悉依赖注入的读者,可以看看由我们翻译的Asp.Net Core中文文档中依赖注入的相关章节: ASP.NET Core 中文文档 第三章 原理(10)依赖注入。基于IoC的重要性,AspectCore在提供Aop特性的同时,同样提供了可以和Aop无缝集成使用的轻量级、高性能IoC容器AspectCore.Injector

开始使用

AspectCore.Injector内置在AspectCore.Core包中,我们可以通过nuget获取

   Install-Package AspectCore.Core -pre

容器和服务注册

在AspectCore.Injector中容器命名为IServiceContainer,使用容器的默认实现来创建一个容器,并且提供了类型,实例,和工厂三种方式来注册服务:

IServiceContainer services = new ServiceContainer();

//使用类型注册服务
services.AddType<ILogger, Logger>(); //使用实例注册服务,服务的生命周期限定为单例
services.AddInstance<ITaskService>(new TaskService()); //使用委托工厂注册服务
services.AddDelegate<ITaskService, TaskService>(resolver => new TaskService());

服务解析

AspectCore.Injector通过IServiceResolver来解析服务:

//创建服务解析器
IServiceResolver serviceResolver = services.Build(); //解析单个服务
ISampleService sampleService = serviceResolver.Resolve<ISampleService>(); //解析单个服务,并且验证是否为null,为null则抛出异常
ISampleService sampleServiceRequired = serviceResolver.ResolveRequired<ISampleService>(); //解析服务集合,如果未注册,则为空集合
IEnumerable<ISampleService> sampleServices = serviceResolver.ResolveMany<ISampleService>();

依赖注入

AspectCore.Injector提供构造器注入和属性两种方式:

public interface ISampleService
{
} public class SampleService : ISampleService
{
private readonly ISampleRepository _sampleRepository;
private readonly ILogger _logger; //构造器注入
public SampleService(ISampleRepository sampleRepository, ILogger logger)
{
_sampleRepository = sampleRepository;
_logger = logger;
}
} public interface ISampleRepository
{
} public class SampleRepository : ISampleRepository
{
//属性注入。属性注入的条件为标记FromContainer特性,并且允许set。满足条件的属性自动注入
[FromContainer]
public ILogger Logger { get; set; }
}

生命周期

AspectCore.Injector提供以下生命周期:

瞬时

瞬时(Transient)生命周期服务在它们每次请求时被创建。这一生命周期适合轻量级的,无状态的服务。

作用域

作用域(Scoped)生命周期服务在每个作用域内被创建一次。

单例

单例(Singleton)生命周期服务在它们第一次被解析时创建,并且每个后续解析将使用相同的实例。如果你的应用程序需要单例行为,建议让服务容器管理服务的生命周期而不是在自己的类中实现单例模式和管理对象的生命周期。

Aop集成

在AspectCore.Injector中默认开启在AspectCore.DynamicProxy的Aop集成,并可通过IServiceContainer的Configure方法进行Aop的配置。

services.Configure(config =>
{
config.Interceptors.AddTyped<SampleInterceptor>();
});

在Asp.Net Core中使用AspectCore.Injector

安装AspectCore.Extensions.DependencyInjection nuget包

    Install-Package AspectCore.Extensions.DependencyInjection -pre

在修改ConfigureServices:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
//添加你的服务... //将IServiceCollection的服务添加到ServiceContainer容器中
var container = services.ToServiceContainer();
return container.Build();
}

只需要两行代码即可在Asp.Net Core中使用AspectCore.Injector替换默认的DependencyInjection。

性能

Autofac是目前.net/.net core较为流行的IoC容器之一,我们把Autofac(4.6.2版本)作为性能对比目标。分别从解析简单对象,属性注入和构造器注入三个方面对比性能。

Benckmark类编写如下:

[AllStatisticsColumn]
[MemoryDiagnoser]
public class Benckmarks
{
private readonly IServiceResolver serviceResolver;
private readonly IContainer container; public Benckmarks()
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Logger>().As<ILogger>().InstancePerDependency();
containerBuilder.RegisterType<TaskService>().As<ITaskService>().InstancePerDependency();
containerBuilder.RegisterType<SampleRepository>().As<ISampleRepository>().InstancePerDependen
containerBuilder.RegisterType<SampleService2>().As<ISampleService>().InstancePerDependency();
container = containerBuilder.Build(); var serviceContainer = new ServiceContainer();
serviceContainer.AddType<ILogger, Logger>(Lifetime.Transient);
serviceContainer.AddType<ITaskService, TaskService>(Lifetime.Transient);
serviceContainer.AddType<ISampleRepository, SampleRepository>(Lifetime.Transient);
serviceContainer.AddType<ISampleService, SampleService2>(Lifetime.Transient);
serviceResolver = serviceContainer.Build();
} [Benchmark]
public object Autofac_Sample_Resolve()
{
return container.Resolve<ITaskService>();
} [Benchmark]
public object AspectCore_Sample_Resolve()
{
return serviceResolver.Resolve<ITaskService>();
} [Benchmark]
public object Autofac_PropertyInjection()
{
return container.Resolve<ISampleRepository>();
} [Benchmark]
public object AspectCore_PropertyInjection()
{
return serviceResolver.Resolve<ISampleRepository>();
} [Benchmark]
public object Autofac_ConstructorInjection()
{
return container.Resolve<ISampleService>();
} [Benchmark]
public object AspectCore_ConstructorInjection()
{
return serviceResolver.Resolve<ISampleService>();
}
}

使用Release模式运行Benchmark:

BenchmarkDotNet=v0.10.8, OS=Windows 10 Threshold 2 (10.0.10586)
Processor=Intel Core i5-4590 CPU 3.30GHz (Haswell), ProcessorCount=4
Frequency=3215206 Hz, Resolution=311.0221 ns, Timer=TSC
dotnet cli version=2.0.0
[Host] : .NET Core 4.6.00001.0, 64bit RyuJIT
DefaultJob : .NET Core 4.6.00001.0, 64bit RyuJIT | Method | Mean | Min | Max | Op/s | Gen 0 | Allocated |
|-------------------------------- |------------:|------------:|------------:|-------------:|-------:|----------:|
| Autofac_Sample_Resolve | 494.83 ns | 482.52 ns | 506.58 ns | 2,020,908.9 | 0.2384 | 752 B |
| AspectCore_Sample_Resolve | 88.52 ns | 87.92 ns | 89.31 ns | 11,296,837.3 | 0.0279 | 88 B |
| Autofac_PropertyInjection | 2,014.46 ns | 2,004.18 ns | 2,028.83 ns | 496,411.0 | 0.5875 | 1856 B |
| AspectCore_PropertyInjection | 307.55 ns | 303.61 ns | 310.74 ns | 3,251,544.6 | 0.1063 | 336 B |
| Autofac_ConstructorInjection | 1,465.71 ns | 1,454.43 ns | 1,480.38 ns | 682,263.5 | 0.6084 | 1920 B |
| AspectCore_ConstructorInjection | 284.94 ns | 283.55 ns | 286.05 ns | 3,509,500.8 | 0.0987 | 312 B |

有问题反馈

Sample:IoC-Sample

如果您有任何问题,请提交 Issue 给我们。

Github : https://github.com/dotnetcore/AspectCore-Framework

AspectCore Group QQ群: 306531723

AspectCore中的IoC容器和依赖注入的更多相关文章

  1. IOC容器的依赖注入

    1.依赖注入发生的时间 当Spring IoC容器完成了Bean定义资源的定位.载入和解析注册以后,IoC容器中已经管理类Bean定义的相关数据,但是此时IoC容器还没有对所管理的Bean进行依赖注入 ...

  2. springboot成神之——ioc容器(依赖注入)

    springboot成神之--ioc容器(依赖注入) spring的ioc功能 文件目录结构 lang Chinese English GreetingService MyRepository MyC ...

  3. 深入分析MVC中通过IOC实现Controller依赖注入的原理

    这几天利用空闲时间,我将ASP.NET反编译后的源代码并结合园子里几位大侠的写的文章认真的看了一遍,收获颇丰,同时也摘要了一些学习内容,存入了该篇文章:<ASP.NET运行机制图解>,在对 ...

  4. ASP.NET中IOC容器Autofac(依赖注入DI 控制反转IOC)

    IOC的一个重点是在程序运行中,动态的向某个对象提供它所需要的其他对象.这一点是通过DI来实现的.Autofac则是比较流行的一款IOC容器. IoC和DI有什么关系呢?其实它们是同一个概念的不同角度 ...

  5. 通过中看不中用的代码分析Ioc容器,依赖注入....

    /** * 通过生产拥有超能力的超人实例 来理解IOC容器 */ //超能力模组接口 interface SuperModuleInterface{ public function activate( ...

  6. spring框架--IOC容器,依赖注入

    思考: 1. 对象创建创建能否写死? 2. 对象创建细节 对象数量 action  多个   [维护成员变量] service 一个   [不需要维护公共变量] dao     一个   [不需要维护 ...

  7. Spring源码解析三:IOC容器的依赖注入

    一般情况下,依赖注入的过程是发生在用户第一次向容器索要Bean是触发的,而触发依赖注入的地方就是BeanFactory的getBean方法. 这里以DefaultListableBeanFactory ...

  8. [spring源码] 小白级别的源码解析IOC容器的依赖注入(三)

    上一篇介绍了ioc容器的初始化过程,主要完成了ioc容器建立beanDefinition数据映射.并没有看到ioc容器对bean依赖关系进行注入. 接口getbean就是出发依赖注入发生的地方.下面从 ...

  9. PHP中的服务容器与依赖注入的思想

    依赖注入 当A类需要依赖于B类,也就是说需要在A类中实例化B类的对象来使用时候,如果B类中的功能发生改变,也会导致A类中使用B类的地方也要跟着修改,导致A类与B类高耦合.这个时候解决方式是,A类应该去 ...

随机推荐

  1. 201521123082《Java程序设计》第4周学习总结

    201521123082<Java程序设计>第4周总结 标签(空格分隔): java 1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内 ...

  2. 201521123048 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 //child public class test extends P ...

  3. Java 第四周总结

    1. 本周学习总结 2. 书面作业 注释的应用: (1)源文件注释采用 /** -- */,在每个源文件的头部要有必要的注释信息,包括:文件名:文件编号:版本号:作者:创建时间:文件描述包括本文件历史 ...

  4. 201521123102 《Java程序设计》第1周学习总结

    #1. 本周学习总结(1)初步了解java程序的运行环境,通过命令行语句编译简单的java程序(2)使用notepad编写,cmd下进入文件夹编译程序(3)学习使用各种快捷键补全代码(4)能够区别jd ...

  5. 201521123064 《Java程序设计》第11周学习总结

    1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. ① 定义Thread类的子类,覆盖Thread类的run()方法,然后创建该子类的实例(一般不用该方法,开销大. ...

  6. 201521123075 《Java程序设计》第10周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中finally中捕获异常需要注意什么? fin ...

  7. 201521123119 《Java程序设计》第13周学习总结

    1. 本周学习总结 Q以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 Q1. 网络基础 Q1.1 比较ping www.baidu.com与ping cec. ...

  8. Hibernate第四篇【集合映射、一对多和多对一】

    前言 前面的我们使用的是一个表的操作,但我们实际的开发中不可能只使用一个表的-因此,本博文主要讲解关联映射 集合映射 需求分析:当用户购买商品,用户可能有多个地址. 数据库表 我们一般如下图一样设计数 ...

  9. C# 各种常用集合类型的线程安全版本

    在C#里面我们常用各种集合,数组,List,Dictionary,Stack等,然而这些集合都是非线程安全的,当多线程同时读写这些集合的时候,有可能造成里面的数据混乱,为此微软从Net4.0开始专门提 ...

  10. 框架应用:Mybatis (一) - 入门案例

    ORM框架 在实际开发中,工程中本质的任务是从数据库中获取数据,然后对数据进行操作,又或者写入数据.开发时语言是大多是面向对象的工程语言,这个时候就必须进行工程语言和数据库连接语言的转换,也就是所谓的 ...