zoukankan      html  css  js  c++  java
  • Autofac依赖注入容器

    依赖注入容器-- Autofac

    https://github.com/danielpalme/IocPerformance

    Unity 更新频率高,微软的项目
    Grace 综合性能更高

    目录:

    一、简介

    二、如何使用

      2.1、基本使用

      2.2、接口使用

      2.3、 其他注入

      2.4、 注入的生命周期


    一、简介

    在上一篇文章中讲到替换默认服务容器,我们选择了Autofac

    Autofac---Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上非常高。

    我们在.Net Core 中替换了自带的默认服务容器,选择采用Autofac,那么如何去使用它呢?

    二、如何使用

    TestController控制器

    public class TestController : Controller
        {
            private static Animals _animals;
    
             public IActionResult Index()
            {
                ViewBag.Animal = _animals.Cry();
                return View();
            }
        }

    替换修改后的Startup.cs 中的ConfigureServices

     public IServiceProvider ConfigureServices (IServiceCollection services)
            {
                services.AddMvc();
                // Add other framework services
                // Add Autofac
    
                var containerBuilder = new ContainerBuilder();
                      
    
                containerBuilder.Populate(services);
                var container = containerBuilder.Build();
                return new AutofacServiceProvider(container);
    
            }

    1.1、  基本使用

    创建 Animals  类

    public class Animals
        {
            public string Cry()
            {
                return "小狗,汪汪汪";
            }
    }

    ConfigureServices   中添加注册

    containerBuilder.RegisterType<Animals>();

    TestController 控制器中添加构造函数

       public TestController(Animals animals)
            {
                _animals = animals;
    
            }

    运行起来看下

     

    1.2、  接口使用

    创建IAnimals.cs

    public interface IAnimals
        {
            string Cry();
        }
    
        public class DogCry : IAnimals
        {
            public string Cry()
            {
                return "小狗,汪汪汪";
            }
        }
        public class CatCry : IAnimals
        {
            public string Cry()
            {
                return "小猫,喵喵喵";
            }
        }

    ConfigureServices   中添加注册

    containerBuilder.RegisterType<DogCry>().As<IAnimals>();

    TestController 控制器中添加构造函数并修改_animals为对应的类型

    public TestController(IAnimals animals)
            {
                _animals = animals;
            }

    运行起来

     

    如果一个类型被多次注册,以最后一个注册的为准

    ConfigureServices   中添加注册

    containerBuilder.RegisterType<DogCry>().As<IAnimals>();
    
    containerBuilder.RegisterType<CatCry>().As<IAnimals>();

    运行起来看下

     

    1.3、  其他注入

    1、 自动装配—从容器里面选择一个构造方法来创建对象

    创建Cry类

    public  class Cry
        {
    
            public   Cry()
            {
                voice= "小狗,汪汪汪";
            }
    
            public  Cry(string voices)
            {
                if (string.IsNullOrWhiteSpace(voices))
                {
                    voice = "旺旺旺";
    
                }
                voice= $"小狗,{voices}";
    
            }
    
            public  Cry(string name, string voices):this(voices)
            {
                if (string.IsNullOrWhiteSpace(voices))
                {
                    voice = "旺旺旺";
                }
                if (string.IsNullOrWhiteSpace(name))
                {
                    voice = "柴犬";
                }
                voice= $"{name},{voices}";
            }
            public static  string voice { get; set; }
    }

    ConfigureServices   中添加注册

    containerBuilder.RegisterType<Cry>().UsingConstructor(typeof(string));

    Autofac会默认从容器中选择参数最多的构造函数,如果想要指定选择的话可以指定UsingConstructor

    2、 实例化注入

    还是上面的Cry类

    ConfigureServices   中添加注册

    var output = new Cry("叫声叫声");
    
    containerBuilder.RegisterInstance(output).ExternallyOwned();

    先对对象实例化然后注册,ExternallyOwned--配置组件,使容器永远不会处理实例。

    修改Test控制器

    public IActionResult Index()
            {
                ViewBag.Animal = Cry.voice;
    
                return View();
            }

    1.4、  注入的生命周期

    1 Transient暂时生存期)--暂时生存期服务是每次从服务容器进行请求时创建的。 这种生存期适合轻量级、 无状态的服务。

    2 Scoped范围生存期)--范围生存期服务是每个客户端请求连接时创建的一次实例

    3 Singleton单例生存期)--单例生存期会在程序第一次请求是创建一次实例,不会变化的

    我们来利用生成guid来看一下三个的生命周期有什么具体的不一样

    修改Test控制器

    public class TestController : Controller
        {
    
            private static IGetTransient _getTransient;
    
            private static IGetScoped _getScoped;
    
            private static IGetSingleton _getSingleton;
    
     
    
            public TestController(IGetTransient getTransient, IGetScoped getScoped, IGetSingleton getSingleton)
            {
                _getTransient = getTransient;
    
                _getScoped = getScoped;
    
                _getSingleton = getSingleton;
            }
    
            public IActionResult Index()
            {
                ViewBag.getTransient = _getTransient.GuidItem();
    
                ViewBag.getScoped = _getScoped.GuidItem();
    
                ViewBag.getSingleton = _getSingleton.GuidItem();
    
                return View();
            }     
    
        }

    修改Index.cshtml

      <div>
            <span>Transient:</span><span>@ViewBag.getTransient</span>
        </div>
    
        <div>
            <span>Scoped:</span><span>@ViewBag.getScoped</span>
        </div>
    
        <div>
            <span>Singleton:</span><span>@ViewBag.getSingleton</span>
        </div>

    IGuid接口

       public interface IGuid
        {
            Guid GuidItem();
        }
    
     
    
        /// <summary>
        /// 暂存生存期
        /// </summary>
        public interface IGetTransient : IGuid
        {
    
        }
    
        /// <summary>
        /// 范围生存期
        /// </summary>
        public interface IGetScoped : IGuid
        {
    
        }
    
        /// <summary>
        /// 单例生存期
        /// </summary>
        public interface IGetSingleton : IGuid
        { 
    
        }

    GuidServiceBase

    public class GuidServiceBase: IGuid
        {
            private readonly Guid _item;
    
             public GuidServiceBase()
            {
                _item = Guid.NewGuid();
            }
    
             public Guid GuidItem()
            {
    
                return _item;
            }
        }
        /// <summary>
        /// 暂存生存期
        /// </summary>
        public class GuidTransientService : GuidServiceBase, IGetTransient
        {
        }
    
        /// <summary>
        /// 范围生存期
        /// </summary>
        public class GuidScopedService : GuidServiceBase, IGetScoped
        {
        }
    
        /// <summary>
        /// 单例生存期
        /// </summary>
        public class GuidSingletonService : GuidServiceBase, IGetSingleton
        {
        }

    ConfigureServices   中添加注册

      

    containerBuilder.RegisterType<GuidTransientService>().As<IGetTransient>();
    
    containerBuilder.RegisterType<GuidScopedService>().As<IGetScoped>().InstancePerLifetimeScope();
    
    containerBuilder.RegisterType<GuidSingletonService>().As<IGetSingleton>().SingleInstance();

     

    运行起来发现Singleton单例生存期)没有变化,仅产生了一个实例,但是Scoped范围生存期) 变化的不一样,按照理论来说应该刷新之后会变化,但是两边应该会是一样的值。--(因为两个页面依然是独立的,并不是一次请求)。我们换另一种方式验证这个

     

    修改Test控制器新增Guid

      public IActionResult Guid()
            {
                return View();
            }

    添加Guid.cshtml通过inject注入依赖

     

    @{
        Layout = null;
    }
    @inject WebApplication3.IGetTransient TransientService
    @inject WebApplication3.IGetScoped GuidScopedService
    @inject WebApplication3.IGetSingleton GuidSingletonService
    <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Guid</title> </head> <body> <div class="row"> <div> <h2>GuidItem Shows</h2> <h3>TransientItem: @TransientService.GuidItem()</h3> <h3>ScopedItem: @GuidScopedService.GuidItem()</h3> <h3>SingletonItem: @GuidSingletonService.GuidItem()</h3> </div> </div> </body> </html>

    修改Index.cshtml

     

    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    @Html.Partial("Guid")
    
    <h1>Guid</h1>
    
    @Html.Partial("Guid")

    运行然后打开两个页面

     

    我们再次完全吻合的,暂时生命周期在每次使用的时候的Guid(实例)都是变化的,范围生命周期在同一个请求范围内Guid是不变化的,不同请求的Guid是会发生变化的。但是单例生命周期的Guid从程序开始就不会发生变化的。

  • 相关阅读:
    如何使用go module导入本地包
    gin-vue-admin 03 项目打包上线
    golang map转xml
    vim简明文档
    goframe gf-cli的使用
    supervisor 的安装与使用
    element Tree 树形控件
    gin-vue-admin开发教程 02 了解项目目录结构和代码执行的流程
    gin-vue-admin开发教程 01安装与启用
    oraclesql遇见的问题(一)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/10967279.html
Copyright © 2011-2022 走看看