龙空技术网

ASP.NET Core 依赖注入系列三

opendotnet 214

前言:

目前朋友们对“net mvc 依赖注入”大概比较着重,兄弟们都需要分析一些“net mvc 依赖注入”的相关内容。那么小编在网上汇集了一些有关“net mvc 依赖注入””的相关知识,希望姐妹们能喜欢,小伙伴们快快来了解一下吧!

8 依赖关系链我们通过一个例子来了解一下依赖链,例如:如果一个alpha的组件有依赖于一个beta的组件,然而beta组件又依赖于另外一个组件gamma,这就形成了一个依赖链,ASP.NET Core 能够很好的解析这个依赖链,让我们通过一个例子来了解在Models文件夹下添加一个新的接口IStorage.cs,定义如下:

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); }}
接下来创建一个新的Storage类继承该接口

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); } }}
这个Storage类针对Product对象定义了一个简单存储机制,现在我们进入Repository类,在构造函数中创建一个IStorage接口的依赖,代码如下:
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; } }}

现在所有方法和属性将使用IStorage对象工作,在这里我们创建一个依赖链:

1 HomeController类依赖于IRepository对象

2 IRepository对象依赖于IStorage对象现在我们告诉ASP.NET Core 服务如何解析依赖链,因此进入Program.cs类,添加下面代码

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类中获取服务

我们可以通过下面代码在Programe类中获取服务

10 Action方法中获取服务

通过Controller构造函数声明依赖是非常昂贵的,我们可以通过在请求的方法中获取服务我们将添加一个[FromServices] 特性在action方法中指定它依赖的服务我们进入HomeController修改Index,使用[FromServices]从方法中获取ProductSum服务, 把ProductSum从构造函数中移除

代码如下:

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); } }}
当Index方法调用时解析ProductSum类型,不在Controller构造时解析

11 ASP.NET Core 工厂方法注入

我们可以使用工厂模式来注册服务,因此你可以使用它创建你自己的逻辑告诉应用程序如果解析依赖,在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文件注入应用程序

我们可以使用依赖注入将JSON文件注入到Controller或者View,让我们展示一下如何指定这个工作在项目根目录创建一个JSON文件命名为mysettings.json, 将下面内容添加到JSON文件中:

{ "Title": "Dependency Injection Tutorial", "Version": 3}

针对这个JSON文件创建一个类,在Models文件夹下创建一个MyJson.cs类

public class MyJson{ public string Title { get; set; } public int Version { get; set; }}
接下来配置应用程序从JSON文件读取到类,因此在你的应用程序中添加下面代码
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 optional reloadOnChange: true);});builder.Services.Configure<MyJson>(builder.Configuration);var app = builder.Build();

现在可以从任何Controller或者View中读取JSON文件的值,因此我们创建一个Controller并命名为SettingsController.cs,在这个控制器中添加构造函数并且添加IOptions<MyJson>类型的参数, 这个参数通过依赖注入的技术提供JSON文件中的值,代码如下:
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(); } }}

我们将这两个值显示到视图中,因此在Views->Settings文件加下添加Index视图,并在视图中添加如下代码:

@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

前面我们介绍了依赖注入JSON文件的值到控制器中,这次我将注入mysettings.json文件值到View中,在前面我们已经在Program.cs类中做配置

在SettingsController中添加一个新的Show方法

public IActionResult Show(){ return View();}
接下来添加名为Show.cshtml的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的值

运行程序输入URL-, 你将看到值显示在View

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中获取依赖注入的服务

源代码地址

参考文献[1]

[2]

标签: #net mvc 依赖注入