7

在 .net core 2.1 和 3.1 中使用 autofac

 3 years ago
source link: https://blog.zhuliang.ltd/2020/09/backend/using-autofac-in-netcore.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在 .net core 2.1 和 3.1 中使用 autofac

create: 2020-09-25 16:38:43 | update: 2020-09-25 17:34:42 本文总阅读量: 27 次  |  文章总字数: 1.2k 字  |  阅读约需: 5 分钟

通过本文你可以获得如何用 autofac 替换 .NET CORE(2.1,3.1) 默认 IOC 容器。

生命周期说明

  • 每个依赖一个实例(Instance Per Dependency) (默认) —-InstancePerDependency()
  • 单一实例(Single Instance) 单例 —-SingleInstance()
  • 每个生命周期作用域一个实例(Instance Per Lifetime Scope)—-InstancePerLifetimeScope()
  • 每个匹配的生命周期作用域一个实例(Instance Per Matching Lifetime Scope)—-InstancePerMatchingLifetimeScope()
  • 每个请求一个实例(Instance Per Request) asp.net web请求—-InstancePerRequest()
  • 每次被拥有一个实例(Instance Per Owned) —-InstancePerOwned()
  • lambda 表达式

示例代码说明:

// 创建注册组件的builder
var builder = new ContainerBuilder();

//根据类型注册组件 ConsoleLogger 暴漏服务:ILogger
builder.RegisterType<ConsoleLogger>().As<ILogger>();

//根据类型注册组件 ConsoleLogger,暴漏其实现的所有服务(接口)
builder.RegisterType<ConsoleLogger>().AsImplementedInterfaces();

// 根据实例注册组件 output  暴漏服务:TextWriter
var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();

//表达式注册组件,这里我们是在构造函数时传参->"musection"   暴漏服务:IConfigReader
builder.Register(c =new ConfigReader("mysection")).As<IConfigReader>();

//表达式注册组件,解析时传参
var service = scope.Resolve<IConfigReader>(
           new NamedParameter("section", "mysection"));     

//反射注册组件,直接注册了ConsoleLogger类(必须是具体的类),如果ConsoleLogger有多个构造函数,将会取参数最多的那个构造函数进行实例化
builder.RegisterType<ConsoleLogger>();

//反射注册组件,手动指定构造函数,这里指定了调用 MyComponent(ILogger log,IConfigReader config)的构造函数进行注册
builder.RegisterType<MyComponent>()
 .UsingConstructor(typeof(ILogger), typeof(IConfigReader));  

 //注册MySingleton类中的静态变量"Instance",ExternallyOwned()函数指定自己控制实例的生命周期,而不是由autofac自动释放
 builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();

//一个组件暴漏两个服务  
builder.RegisterType<CallLogger>().As<ILogger>().As<ICallInterceptor>(); 

//注册当前程序集中以“Service”结尾的类
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces();
//注册"MyApp.Repository"程序集中所有的类
builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();

//构建一个容器完成注册
var rootcontainer = builder.Build();

//可以通过下面这种方式手动获取IConfigReader 的实现类
//这种手动解析的方式需要 从生命周期作用域内获取组件,以保证组件最终被释放
//不要直接从根容器rootcontainer中解析组件,很有可能会导致内存泄漏
using(var scope = rootcontainer.BeginLifetimeScope())
{
  var reader = scope.Resolve<IConfigReader>();
}

在 ASP.NET CORE 2.1 中的使用

.NET CORE 2.2 和 3.1 对 Autofac 的初始化方式不一样,需要注意下,建议使用 3.1。

需要安装一下的库:

  • [email protected]
  • [email protected]

    注册策略:Module

    在不同层中定义一个 ModuleRegister 类,用于注册类型
  • 这里以 Application 层为例,多层的话可以分别进行定义

IocPolicy.cs

public class IocPolicy : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        //注册当前程序集中以“Ser”结尾的类,暴漏类实现的所有接口,生命周期为PerLifetimeScope
        builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().SingleInstance();
        //注册所有"MyApp.Repository"程序集中的类
        //builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
    }
}

接管默认 IoC 引擎

需要修改 Startup.cs,需要调整 ConfigServices 方法签名,以让 autofac 接管 ioc

public static IContainer AutofacContainer;
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            #region >>AutoFac  1/2
            ContainerBuilder builder = new ContainerBuilder();
            //将services中的服务填充到Autofac中.
            builder.Populate(services);
            //新模块组件注册
            builder.RegisterModule<Application.IocPolicy>();
            builder.RegisterModule<Domain.IocPolicy>();
            //创建容器.
            AutofacContainer = builder.Build();
            //使用容器创建 AutofacServiceProvider 
            return new AutofacServiceProvider(AutofacContainer);
            #endregion
        }


        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime appLifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
             #region >>AutoFac  2/2
            //程序停止调用函数
            appLifetime.ApplicationStopped.Register(() => { AutofacContainer.Dispose(); });
            #endregion
        }

在 ASP.NET CORE 3.1 中的使用

这里跟 core 2.2不一样,更加偏向于默认的 IoC 容器了,也方便了不少。

需要安装以下的库:

IocPolicy.cs

public static class IocPolicy
{
    public static void RegisterApplication(this ContainerBuilder builder)
    {
        //注册当前程序集中以“Ser”结尾的类,暴漏类实现的所有接口,生命周期为PerLifetimeScope
        builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().SingleInstance();
        //注册所有"MyApp.Repository"程序集中的类
        //builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
    }
}

接管默认 IoC 引擎

需要修改 Startup.cs,需要调整 ConfigServices 方法签名,以让 autofac 接管 ioc

/* 新增加如下方法,用于注册类型 */

        public void ConfigureContainer(ContainerBuilder builder)
        {
            #region >>AutoFac
            builder.RegisterApplication();
            builder.RegisterDomain();
            #endregion
        }

Program.cs

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK