namespace AspNetCore.DependencyInjection.Models{public interface IStorage{IEnumerable<Product> Items { get; }Product this[string key] { get; set; }bool ContainsKey(string key);void RemoveItem(string key);}}
namespace AspNetCore.DependencyInjection.Models{public class Storage : IStorage{private Dictionary<string, Product> items = new Dictionary<string, Product>();public Product this[string key]{get { return items[key]; }set { items[key] = value; }}public IEnumerable<Product> Items => items.Values;public bool ContainsKey(string key){return items.ContainsKey(key);}public void RemoveItem(string key){items.Remove(key);}}}
namespace AspNetCore.DependencyInjection.Models{public class Repository : IRepository{private IStorage _storage;public Repository(IStorage storage){_storage = storage;new List<Product> {new Product { Name = "Women Shoes", Price = 99M },new Product { Name = "Skirts", Price = 29.99M },new Product { Name = "Pants", Price = 40.5M }}.ForEach(p => AddProduct(p));}public IEnumerable<Product> Products => _storage.Items;public Product this[string name] => _storage[name];public void AddProduct(Product product) => _storage[product.Name] = product;public void DeleteProduct(Product product) => _storage.RemoveItem(product.Name);private string guid = Guid.NewGuid().ToString();public override string ToString(){return guid;}}}
var builder = WebApplication.CreateBuilder(args);//builder.Services.AddTransient<IRepository, Repository>();//builder.Services.AddScoped<IRepository, Repository>();//builder.Services.AddSingleton<IRepository,Repository>();builder.Services.AddTransient<ProductSum>();builder.Services.AddTransient<IRepository, Repository>();builder.Services.AddTransient<IStorage, Storage>();// Add services to the container.builder.Services.AddControllersWithViews();var app = builder.Build();
重新运行你的应用程序你将看到有所有的产品将显示在浏览器中

9 在Programe类中获取服务

10 Action方法中获取服务
代码如下:
namespace AspNetCore.DependencyInjection.Controllers{public class HomeController : Controller{private IRepository _repository;public HomeController(IRepository repository){_repository = repository;}public IActionResult Index([FromServices] ProductSum _productSum){ViewBag.HomeControllerGUID = _repository.ToString();ViewBag.TotalGUID = _productSum.Repository.ToString();return View(_repository.Products);}}}
我们可以使用工厂模式来注册服务,因此你可以使用它创建你自己的逻辑告诉应用程序如果解析依赖,在Models文件夹下创建一个新的类ProductionRepository.cs,代码如下:
namespace AspNetCore.DependencyInjection.Models{public class ProductionRepository : IRepository{private Dictionary<string, Product> products;public ProductionRepository(){products = new Dictionary<string, Product>();new List<Product> {new Product { Name = "Women Shoes", Price = 99M },new Product { Name = "Skirts", Price = 29.99M },new Product { Name = "Pants", Price = 40.5M }}.ForEach(p => AddProduct(p));}public IEnumerable<Product> Products => products.Values;public Product this[string name] => products[name];public void AddProduct(Product product) => products[product.Name] = product;public void DeleteProduct(Product product) => products.Remove(product.Name);}}
现在我们在开发环境和生产环境中分别注册不同的服务,我们通过函数代理并且添加lambda函数创建

12 把JSON文件注入应用程序
{"Title": "Dependency Injection Tutorial","Version": 3}
针对这个JSON文件创建一个类,在Models文件夹下创建一个MyJson.cs类
public class MyJson{public string Title { get; set; }public int Version { get; set; }}
using DependencyInjection.Models;var builder = WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddControllersWithViews();builder.Host.ConfigureAppConfiguration((hostingContext, config) =>{config.AddJsonFile("mysettings.json",optional: false, //file is not optionalreloadOnChange: true);});builder.Services.Configure<MyJson>(builder.Configuration);var app = builder.Build();
using DependencyInjection.Models;using Microsoft.AspNetCore.Mvc;using Microsoft.Extensions.Options;namespace DependencyInjection.Controllers{public class SettingsController : Controller{private readonly MyJson _settings;public SettingsController(IOptions<MyJson> settingsOptions){_settings = settingsOptions.Value;}public IActionResult Index(){ViewData["Title"] = _settings.Title;ViewData["Version"] = _settings.Version;return View();}}}
@if (ViewData.Count > 0){<table class="table table-bordered table-sm table-striped">@foreach (var kvp in ViewData){<tr><td>@kvp.Key</td><td>@kvp.Value</td></tr>}</table>}

13 View中获取依赖注入对象
使用@inject指令可以在ASP.NET Core View 中使用依赖注入,我们通过两个例子来了解:
13.1 将JSON文件注入到View
在SettingsController中添加一个新的Show方法
public IActionResult Show(){return View();}
@using Microsoft.Extensions.Options;@using AspNetCore.DependencyInjection.Models@inject IOptions<MyJson> settingsOptions<table class="table table-bordered table-sm table-striped"><tr><td>Title</td><td>@settingsOptions.Value.Title</td></tr><tr><td>Version</td><td>@settingsOptions.Value.Version</td></tr></table>
注意:通过下面代码显示JSON的值


13.2 appsettings.json注入View
我们可以将appsettings.json文件的值注入的view,这个过程非常简单,你只需要使用inject指令然后显示他们的值,代码如下:
@inject IConfiguration Configuration<div>@Configuration["Logging:LogLevel:Default"]</div>
我们将下面appsettings.json文件的值显示到页面
{"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*"}
我们将显示Default,Microsoft.AspNetCore节点的值,在SettingsController中添加Detail方法
public IActionResult Detail(){return View();}
在Detail视图中添加如下代码
@inject IConfiguration Configuration<table class="table table-bordered table-sm table-striped"><tr><td>Default</td><td>@Configuration["Logging:LogLevel:Default"]</td></tr><tr><td>Microsoft</td><td>@Configuration["Logging:LogLevel:Default"]</td></tr><tr><td>Microsoft.Hosting.Lifetime</td><td>@Configuration["Logging:LogLevel:Microsoft.AspNetCore"]</td></tr></table>

总结
这节中我们主要讲解了如何在ASP.NET Core中使用依赖注入,以及依赖注入对象的方法,以及使用不同方法注入时对象的生命周期,在Programe和Action方法以及View中获取依赖注入的服务
源代码地址
https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.DependencyInjection/AspNetCore.DependencyInjection