专栏首页.Net、.Net Core 、Docker依赖注入容器-- Autofac

依赖注入容器-- Autofac

目录:

一、简介

二、如何使用

  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从程序开始就不会发生变化的。


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 通俗易懂设计模式解析——抽象工厂模式

      前面介绍了单例模式及工厂模式相关知识及示例,今天主要介绍的是抽象工厂模式,上一篇我们讲了工厂模式。将创建对象的任务委托给子类,延迟创建。解决工厂中责任的划分...

    小世界的野孩子
  • 通俗易懂设计模式解析——装饰模式

      今天介绍的是结构型设计模式中的——装饰模式(Decorator Pattern),也是装饰器模式。装饰也就是装点修饰。例如我们对手机进行装饰,买了一个新的手...

    小世界的野孩子
  • 委托与事件-委托事件案例(三)

      这两天一直在想如何结合实际案例来结束委托与事件的讲解,下面讲解两个事例,用来加深对委托及事件的理解。

    小世界的野孩子
  • Java面向对象之抽象类,接口

    抽象类: 含有抽象方法的类被声明为抽象类 抽象方法由子类去实现 含有抽象方法的类必须被声明为抽象类 抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中...

    二十三年蝉
  • Java内功心法,行为型设计模式

    使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。 将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。

    李红
  • 设计原则

    一、面向对象应用程序开发原则(SOLID) 1单一职责原则(SRP) 定义: 一个类应该只有一个发生变化的原因。这条原则曾被称为内聚性,即一个模块的组成元素之间...

    甜橙很酸
  • ASP.NET Web API中的依赖注入什么是依赖注入ASP.NET Web API依赖解析器使用Unity解析依赖配置依赖解析

    什么是依赖注入     依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型...

    小白哥哥
  • 23种设计模式详解(三)

    模板方法模式就是指:一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类...

    南风
  • (52) 抽象容器类 / 计算机程序的思维逻辑

    查看历史文章,请点击上方链接关注公众号。 从38节到51节,我们介绍的都是具体的容器类,上节我们提到,所有具体容器类其实都不是从头构建的,它们都继承了一些抽象容...

    swiftma
  • 图解Java设计模式

    只要是在类中用到了对方,那么他们之间就存在依赖关系。如果没有对方,连编 绎都通过不了。

    编程之心

扫码关注云+社区

领取腾讯云代金券