C# 初使autofac IOC容器

  先捋下概念。

  IOC 称Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想,这种思想最大的好处是解耦,依赖于接口而非依赖于实例,充分体现了面向接口编程,方便日后维护和迭代。

  DI 称Dependency Injection,即"依赖注入",他是一个技术,要想实现IOC设计思想,我们就需要借助DI这个技术,他能够根据引用无限制的注入(比如类A引用到类B,类B又引用类C),旧的New方式使用类A的话,我们需要分别New出类B和类C的实例。如果使用IOC这种设计的话,我们就可以借助DI自动进行无限注入,不需要关心他的引用。

  IOC容器有很多,我目前接触到了.Net Core内置的IServiceCollection和第三方autofac。了解更多可以去百度。这里不在列出。

  

 

 

 

  既然我们把创建对象的工作交给了IOC,IOC就可以在创建的时候搞些事情,比如对象的生命周期和AOP

  

1、瞬时 InstancePerDependency:每次获取的服务实例都不一样;

2、单例 SingleInstance:在整个容器中获取的服务实例都是同一个;

3、作用域 InstancePerLifetimeScope:相同作用域下获取到的服务实例相同;

4、作用域 InstancePerMatchingLifetimeScope(“作用域名称”):可以指定到某一个具体作用域;

5、每次请求 InstancePerRequest:不同的请求获取的服务实例不一样;

6、隐式关系类型的嵌套作用域 InstancePerOwned:可以使用每一个拥有实例的注册来依赖关系限定到拥有的实例。

  下面简单说下autofac的使用。网上有很多单个类使用的方式,这里不再写了,实际项目也不会单个类一个一个注入。更多的是通过封装自动注入所有类。

  使用第三方IOC容器Autofac,首先需要引用Autofac,Autofac.Extensions.DependencyInjection两个包。

  项目结构

 

  我把IOC注入的工作写到了Util类中。

  1.首先定义几个常用的生命周期接口(目的是自动注册的时候知道这个类需要的生命周期)

 

 

定义接口的时候继承于上面定义的生命周期

 

 

 

 

    2.定义程序集类(获取所有程序集进行注册IOC)

 

 

 

  3.编写autofac扩展类(通过查询程序集的类进行注入)

 

using Autofac;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;

namespace MrZhu.Util
{
/// <summary>
/// Autofac拓展类
/// </summary>
public class ApiModule:Autofac.Module
{
//private static readonly ProxyGenerator _generator = new ProxyGenerator();
protected override void Load(ContainerBuilder builder)
{
// 获取所有创建的项目Lib
var libs = GlobalAssemblies.AllAssemblies;

// 将lib转成Assembly
List<Assembly> assemblies = new();
foreach (var lib in libs)
{
assemblies.Add(lib);
}

// 反射获取其中所有的被接口修饰的类型,并区分生命周期
builder.RegisterAssemblyTypes(assemblies.ToArray())
.Where(t => t.IsAssignableTo<IocTagScope>() && !t.IsAbstract)
.AsSelf()
.AsImplementedInterfaces()
.InstancePerLifetimeScope()
.PropertiesAutowired();

builder.RegisterAssemblyTypes(assemblies.ToArray())
.Where(t => t.IsAssignableTo<IocTagSington>() && !t.IsAbstract)
.AsSelf()
.AsImplementedInterfaces()
.SingleInstance()
.PropertiesAutowired();

builder.RegisterAssemblyTypes(assemblies.ToArray())
.Where(t => t.IsAssignableTo<IocTagTransient>() && !t.IsAbstract)
.AsSelf()
.AsImplementedInterfaces()
.PropertiesAutowired();

builder.RegisterAssemblyTypes(assemblies.ToArray())
.Where(t => t.IsAssignableTo<ControllerBase>() && !t.IsAbstract)
.AsSelf()
.PropertiesAutowired();
}
}
}

   4.最后一步Web项目中Program.cs注册IOC

 

 

//注册Autofac
//将控制器类注册到容器中
builder.Services.AddControllers().AddControllersAsServices();

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
// builder.AutofacExtensions();
builder.RegisterModule<ApiModule>();
});

调试查看效果(通过注入已经可以根据接口自动调用BLL的方法,实现面向接口编程)

 

posted @ 2023-02-15 15:18  ﹎潴潴﹖  阅读(127)  评论(0编辑  收藏  举报