首页 > 编程语言 >c#中的IOC容器之Autofac容器

c#中的IOC容器之Autofac容器

时间:2022-12-18 05:44:05浏览次数:55  
标签:容器 Autofac service c# IMicrophone sp GetService public

IOC(inversion of control)控制反转

以前我们把框架分为三层架构:UI层,BLL层,DAL层。在三层架构中我们,我们是一层一层的调用对象里面的方法,需要实例化对象:类名  对象名 = new 类名();这种叫传统工艺。
现在我们不需要在依赖某一个类来获取到实例。而是依赖于抽象,怎么获取?交给了第三方(称:IOC容器)通过抽象(接口,抽象类,普通父类)的方式获取到类的实例。
IOC内置容器:ServiceCollection
1.创建库类接口【Interfaces】里面什么都不写,只是做依赖注入的关系

public interface IMicrophone{ }

2.创建一个服务类库【Services】做我们需要调用的具体对象

public class Microphone: IMicrophone
{
     public Microphone() { Console.WriteLine($"{this.GetType().Name}被构造了"); }
}

3.通过容器依赖注入到项目中来

using Interfaces;//接口类库
using Services;//服务类库
using Microsoft.Extensions.DependencyInjection;//内置IOC容器

ServiceCollection service = new ServiceCollection();//1.创建一个容器,需要nuget引入:Microsoft.Extensions.DependencyInjection
service.AddTransient<IMicrophone, Microphone>();//2.建立关系或是注册抽象和具体普通类之间的关系,注册方式有很多,这里只是其中一种
ServiceProvider sp = service.BuildServiceProvider();//3.进行集中管理,统一注入到ServiceProvider,而BuildServiceProvider就是获取依赖关系
IMicrophone microphone= sp.GetService<IMicrophone>();//4.获取抽象的具体实例,就相当于Microphone被实例化后的具体对象,通过接口抽象出来的

传统工艺:new 实例化对象。对象创建在项目中是多个地方的。
ioc容器可以在全局,配置抽象和具体普通类之间的关系,是可以修改AddTransient<抽象, 具体类>();修改为什么获取的就是什么。
ioc容器,最大的好处在于DI依赖注入:如果A依赖于B,B依赖于C;那么在创建A时,会把C先创建出来交给B,在把B创建出来交给A,从而创建出A对象来。

public interface IHeadphone{ }//接口

public class Headphone : IHeadphone //依赖于IPower
{
    public Headphone(IPower power) { Console.WriteLine($"{this.GetType().Name}被构造了"); }
}

Power依赖于IMicrophone

public interface IPower { } //接口

public class Power : IPower
{
    public Power(IMicrophone microphone) { Console.WriteLine($"{this.GetType().Name}被构造了"); }
}

Microphone有继承了IMicrophone

public interface IMicrophone{ }//接口

public class Microphone: IMicrophone
{
    public Microphone() { Console.WriteLine($"{this.GetType().Name}被构造了"); }
}

这种依赖注入关系叫构造函数注入

using Interfaces;//接口类库
using Services;//服务类库
using Microsoft.Extensions.DependencyInjection;//内置IOC容器

Console.WriteLine("传统工艺,实例化对象-------------------");
IMicrophone m =new Microphone();
IPower p = new Power(m);
IHeadphone h = new Headphone(p);

Console.WriteLine("IOC容器支持的依赖注入-----------------------");
ServiceCollection service = new ServiceCollection();//1.创建容器:ioc容器本质就是个工厂用来创建对象的
service.AddTransient<IMicrophone, Microphone>();//2.建立关系
service.AddTransient<IPower, Power>();
service.AddTransient<IHeadphone, Headphone>();
ServiceProvider sp = service.BuildServiceProvider();//3.进行集中管理,获取依赖关系
IHeadphone headphone = sp.GetService<IHeadphone>();//4.获取实例

依赖注入有三种【1.构造函数注入;2.方法注入;3.属性注入】但内置ioc容器只支持构造函数注入,其他两种只能去扩展
ServiceCollection的生命周期

ServiceCollection service = new ServiceCollection();
service.AddTransient<IMicrophone, Microphone>();//Transient:瞬时生命周期,每一次创建都是新的实例
service.AddSingleton<IHeadphone, Headphone>();//Singleton:单例的生命周期,相同的一个引用地址,同一对象实例
service.AddScoped<IPower, Power>();//Scoped:作用域生命周期,保存在相同的ServiceProvider对象里,获取是相同的实例,反之不同
ServiceProvider sp = service.BuildServiceProvider();//获取依赖关系保存到对象
IMicrophone m1 = sp.GetService<IMicrophone>(); 
IMicrophone m2 = sp.GetService<IMicrophone>();
Console.WriteLine($"Transient:瞬时生命周期比较m1和m2是否一样:{object.ReferenceEquals(m1,m2)}");
IHeadphone h1 = sp.GetService<IHeadphone>();
IHeadphone h2 = sp.GetService<IHeadphone>();
Console.WriteLine($"Singleton:单例生命周期比较h1和h2是否一样:{object.ReferenceEquals(h1, h2)}");
IPower p1 = sp.GetService<IPower>();
IPower p2 = sp.GetService<IPower>();
Console.WriteLine($"Scoped:作用域生命周期比较p1和p2是否一样:{object.ReferenceEquals(p1, p2)}");

ServiceCollection的多种注册:上面使用的是泛型注册

ServiceCollection service = new ServiceCollection();
service.AddTransient(typeof(IMicrophone), typeof(Microphone));//方法注册和泛型注册一样的
service.AddTransient(typeof(Microphone));//可以直接给个具体实例,调用也是实例
service.AddTransient<Microphone>();//泛型注册,也可以直接给一个实例
service.AddTransient(typeof(IPower), a => { //委托,注册抽象和一段业务逻辑
    //在这里我们可以直接来决定创建这个对象的实例,可以对这个实例做加工。
    IMicrophone m = a.GetService<IMicrophone>();
    return new Power(m);
});
ServiceProvider sp = service.BuildServiceProvider();
IMicrophone m1 = sp.GetService<IMicrophone>();
Microphone m2 = sp.GetService<Microphone>();//泛型注册也是一样的,可以直接给一个实例
IPower p = sp.GetService<IPower>();

ServiceCollection容器在asp.net core中的使用:首先在【Program.cs】

builder.Services.AddTransient<IMicrophone, Microphone>();//依赖:在顶级程序中注册内置ioc容器。

注入:到控制器(构造方法)中注入使用

private readonly IMicrophone microphone;public HomeController(IMicrophone microphone, IServiceProvider sp)//home控制器的构造方法
{
    this.microphone = microphone;//方法1:注入进来的ioc容器
    this.microphone = sp.GetService<IMicrophone>();//方法2::这两种获取方式是一样
}

Autofac

新的容器替代内置容器,需要引入:

标签:容器,Autofac,service,c#,IMicrophone,sp,GetService,public
From: https://www.cnblogs.com/longxinyv/p/16989932.html

相关文章

  • 解决Mac在Chrome播放视频时缓存写入ssd过猛问题,内存交换直彪
    都知道mac的ssd焊死在主板上ssd的报废意味着你又能换新mac了这些天我发现chrome挂直播看世界杯时候内存占用异常的高赶忙发现在浏览器播放视频时写入ssd的速度直线飙升......
  • VC6的sort不是传说的那么差嘛
    #include<stdio.h>#include<stdlib.h>#include<memory.h>#include<time.h>#include<algorithm>#include<functional>intn_cp,n_cmp,total_cp[2],total_c......
  • [PingCTF2022] 题目分享 - S1gMa
    前言本题来自PingCTF2022-guesswhat,早上12点被树木喊起来对超极长的代码审计和写\(exp\),俩人之间干到下午\(6\)点,对着一个不存在的错误\(debug\)了\(4\)个小时......
  • 「REMAKE C++」Day 3
    Day3完成了C++Primer第4,5章的阅读常量迭代器,不能修改其所指向的对象,可以移动它,vector<int>::const_iteratorit=v.begin();,常量容器只有常量迭代器。标......
  • rsync数据镜像工具
    rsync功能介绍rsync是Linux系统下的数据镜像备份工具,通过rsync可以将本地系统数据通过网络备份到任何远程主机上。rsync有如下特性:可以镜像保存整个目录树和文件系统......
  • Playable API - 多个Animation Clip间切换播放
    #用到的脚本usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.Animations;usingUnityEngine.Playables;publicclassPlayAnimClipOneByO......
  • Playable API - 简单播放Animation Clip
    用到的资源:GitHub-unity3d-jp/unitychan-crs:Unity-Chan"CandyRockStar"LiveDemo这边直接在他提供的Scene上修改PlayableAPI来播放AnimationClip的脚本:usin......
  • 将ChatGPT接入微信实现智能回复
    ChatGPT近期以强大的对话和信息整合能力风靡全网,可以写代码、改论文、讲故事,几乎无所不能,这让人不禁有个大胆的想法,能否用他的对话模型把我们的微信打造成一个智能机器人,......
  • EF Core无法翻译groupby等子查询
    烦人的表达式转化错误varquery1=emps.Grouby(v=>v.DeptId).Select(g=>new{DeptId=g.Key,Salary=g.Max(x=>x.Salary);varresult=fromdindeptsjoi......
  • calendar
    exportconstweekMapZh=['日','一','二','三','四','五','六'];constcalendarGrid=42;//7*6宫格;exportinterfaceCalendarItem{year:number;......