• 基于autofac的属性注入


    基于autofac的属性注入

    什么是属性注入

    在了解属性注入之前,要先了解一下DI(Dependency Injection),即依赖注入。在ASP.NET Core里自带了一个IOC容器,而且程序支行也是基于这个容器建立起来的,在 Startup 里的 ConfigureService 方法里向容器注册服务类型。

    简单来说,依赖注入就是容器帮我们“new”一个对象,并且管理对象的生命周期。

    在依赖注入时,最常用的是构造方法注入。还有另一种方法,那就是属性注入

    在ASP.NET Core中,自带的容器是不支持属性注入的,但是可以通过替换容器来实现,也就是今天介绍的:通过 Autofac 来实现属性注入。

    autofac简介

    Autofac 是一款超赞的.NET IoC 容器 . 它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改 . 它的实现方式是将常规的.net类当做 组件 处理.

    中文文档:https://autofaccn.readthedocs.io/zh/latest/

    为什么要使用属性注入

    主要有以下三点:

    1. 减少常用类型的重复注入代码,使构造方法看起来更为简洁,提高阅读性。
    2. 减少或消除因构造方法注入造成子类继承后的 base 调用链。
    3. 并非是满足第一条或第二条就需要使用属性注入来解决,只有当第一、二条发生的情况到达一定的数量。

    具体实现

    1、引用类库

    Autofac
    Autofac.Extensions.DependencyInjection
    

    2、在 Program.cs 里替换系统默认容器

    public static IHostBuilder CreateHostBuilder(string[] args) =>
    	Host.CreateDefaultBuilder(args)
    		.UseServiceProviderFactory(new AutofacServiceProviderFactory())     // 使用 autofac 的容器工厂替换系统默认的容器
    		.ConfigureWebHostDefaults(webBuilder =>
    		{
    			webBuilder.UseStartup<Startup>();
    		});
    

    3、在 Startup.csConfigureServices 里替换控制器的替换规则

    public void ConfigureServices(IServiceCollection services)
    {
        // 替换控制器的替换规则
    	services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
    
        // other configure
    	services.AddControllers();
    }
    

    4、创建 AutowiredAttribute.cs ,用于标识使用属性注入

    [AttributeUsage(AttributeTargets.Property)]
    public class AutowiredAttribute : Attribute
    {
    }
    

    5、创建 AutofacModule.cs ,注册服务

    /// <summary>
    /// 容器注册类
    /// </summary>
    public class AutofacModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // Register your own things directly with Autofac, like:
            builder.RegisterType<HelloService>().As<IHelloService>().InstancePerDependency().AsImplementedInterfaces();
    
    		// 获取所有控制器类型并使用属性注入
            var controllerBaseType = typeof(ControllerBase);
            builder.RegisterAssemblyTypes(typeof(Program).Assembly)
                .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
                .PropertiesAutowired(new AutowiredPropertySelector());
        }
    }
    
    /// <summary>
    /// 属性注入选择器
    /// </summary>
    public class AutowiredPropertySelector : IPropertySelector
    {
        public bool InjectProperty(PropertyInfo propertyInfo, object instance)
        {
            // 带有 AutowiredAttribute 特性的属性会进行属性注入
            return propertyInfo.CustomAttributes.Any(it => it.AttributeType == typeof(AutowiredAttribute));
        }
    }
    

    6、在 Startup.cs 的 方法 ConfigureContainer 里注册上一步创建的 Module

    // ConfigureContainer is where you can register things directly
    // with Autofac. This runs after ConfigureServices so the things
    // here will override registrations made in ConfigureServices.
    // Don't build the container; that gets done for you. If you
    // need a reference to the container, you need to use the
    // "Without ConfigureContainer" mechanism shown later.
    public void ConfigureContainer(ContainerBuilder builder)
    {
        builder.RegisterModule(new AutofacModule());
    }
    

    示例代码下载:源码

    使用效果

    [Autowired]
    private IHelloService HelloService { get; set; }
    

    在控制器里添加服务属性,然后添加 [Autowired] 特性标识为属性注入即可。

    关于属性注入的注意事项

    属性注入很好用,但是要慎重使用,因为属性注入会造成类型的依赖关系隐藏,测试不友好等。

    建议:在封闭框架时可以使用,但不能大范围使用,只有必须使用属性注入来达到效果的地方才会使用,用来提高使用框架时的编码效率,来达到一些便利,脱离框架层面,编写业务代码时,不得使用。

    参考资料

    主要参考文章:

    使用 autofac 实现 asp .net core 的属性注入
    ASP.NETCore 3.0 Autofac替换及控制器属性注入及全局容器使用 - 情·深 - 博客园

    autofac 的官方示例:
    autofac/Examples: Example projects that consume and demonstrate Autofac IoC functionality and integration

    autofac 文档:
    Welcome to Autofac’s documentation! — Autofac 5.2.0 documentation
    欢迎来到 Autofac 中文文档! — Autofac 4.0 文档

    其它:
    ASP.NET Core 奇淫技巧之伪属性注入 - 晓晨Master - 博客园
    .net core2.0下Ioc容器Autofac使用 - 焰尾迭 - 博客园

  • 相关阅读:
    jQuery 简单滑动轮播图效果
    西工大:同学你好,回来挂科!
    【入门】产品经理零基础怎么入门?
    【考点】 HashMap,HashTable,CurrentHashMap,LinkedHashMap,TreeMap简述
    P图鬼才们集体上线!高校毕业照P图哪家强?
    【实战】怎样实现前端裁剪上传图片功能
    校招选产品经理岗?给你浇盆水
    战胜70%对手的校招开发岗简历是这个样子的
    两个人遇到熊,装死的和转身跑的,哪个能活下来
    第一份实习工作,我应该学到什么?
  • 原文地址:https://www.cnblogs.com/liang24/p/14541650.html
Copyright © 2020-2023  润新知