目录:
一, 简介
二, 如何使用
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 从程序开始就不会发生变化的.
来源: https://www.cnblogs.com/hulizhong/p/10770578.html