1.ASP.NET Core MVC依赖注入

1.依赖注入步骤

步骤一:使用接口或基类将依赖关系实现抽象化。

//IMyDependency接口定义了WriteMessage方法
public interface IMyDependency
{
    void WriteMessage(string message);
}

//MyDependency具体类实现了IMyDependency接口
public class MyDependency : IMyDependency
{
    public void WriteMessage(string message)
    {
        Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
    }
}

步骤二:使用 WebApplicationBuilder.Servicesbuilder.Services 的服务注册方法将服务添加到内置的DI服务容器 IServiceProvider 中。

using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services;

var builder = WebApplication.CreateBuilder(args);

//使用AddScoped服务注册方法(此方法注册的服务生存期是范围内的)注册IMyDependency服务和MyDependency具体类。

builder.Services.AddScoped<IMyDependency, MyDependency>();

var app = builder.Build();

步骤三:将服务注入到依赖该服务的类的构造函数中。

public class Index2Model : PageModel
{
    private readonly IMyDependency _myDependency;

    public Index2Model(IMyDependency myDependency)
    {
        _myDependency = myDependency;            
    }

    public void OnGet()
    {
        _myDependency.WriteMessage("Index2Model.OnGet");
    }
}

2.使用扩展方法注册服务组

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

var app = builder.Build();

可以将相关的注册组移动到扩展方法以注册服务。

约定使用单个 Add{GROUP_NAME} 扩展方法来注册一组相关服务。比如:AddRazorPagesAddControllersAddControllersWithViewsAddDbContext 和 AddDefaultIdentity等等。

建议应用遵循在 Microsoft.Extensions.DependencyInjection 命名空间中创建扩展方法的命名约定。

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }
    }
}
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddConfig(builder.Configuration);

builder.Services.AddRazorPages();

var app = builder.Build();

3.服务生存期

生存期长度:单例生存期>范围内生存期>暂时生存期,所以从暂时或其它范围内生存期服务可以解析范围内生存期服务,从暂时或范围内生存期服务可以解析单例生存期服务。从具有较长生存期的其它服务解析服务将会引发异常。

生存期名称服务注册方法同一个范围新范围
暂时(Transient)AddTransient新实例新实例
范围内(Scoped)AddScoped同一个实例新实例
单例(Singleton)AddSingleton同一个实例同一个实例

4.服务注册方法

以下任何服务注册方法都可用于注册同一服务类型的多个实现。

方法自动
对象
释放
多种
实现
传递参数
Add{LIFETIME}<{SERVICE}, {IMPLEMENTATION}>()
示例:
services.AddSingleton<IMyDep, MyDep>();
Add{LIFETIME}<{SERVICE}>(sp => new {IMPLEMENTATION})
示例:
services.AddSingleton<IMyDep>(sp => new MyDep());
services.AddSingleton<IMyDep>(sp => new MyDep(99));
Add{LIFETIME}<{IMPLEMENTATION}>()
示例:
services.AddSingleton<MyDep>();
AddSingleton<{SERVICE}>(new {IMPLEMENTATION})
示例:
services.AddSingleton<IMyDep>(new MyDep());
services.AddSingleton<IMyDep>(new MyDep(99));
AddSingleton(new {IMPLEMENTATION})
示例:
services.AddSingleton(new MyDep());
services.AddSingleton(new MyDep(99));

MyService 定义两个构造函数参数:一个是 IMyDependency,另一个是 IEnumerable<IMyDependency>

当使用 IMyDependency 类型调用时,第二个AddSingleton会重写第一个AddSingleton,所以 IMyDependency 是已注册的最后一个实现。

当使用 IEnumerable<IMyDependency> 类型调用时,第二个AddSingleton会添加到第一个AddSingleton,所以IEnumerable<IMyDependency> 表示所有已注册的实现。通过 IEnumerable<{SERVICE}> 解析服务时,服务按其注册顺序显示。

services.AddSingleton<IMyDependency, MyDependency>();
services.AddSingleton<IMyDependency, DifferentDependency>();

public class MyService
{
    public MyService(IMyDependency myDependency, 
       IEnumerable<IMyDependency> myDependencies)
    {
        Trace.Assert(myDependency is DifferentDependency);

        var dependencyArray = myDependencies.ToArray();
        Trace.Assert(dependencyArray[0] is MyDependency);
        Trace.Assert(dependencyArray[1] is DifferentDependency);
    }
}

5.框架提供的服务

下表列出了框架提供的服务的一小部分:

服务类型生存期
Microsoft.Extensions.DependencyInjection.IServiceScopeFactory单例
Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory暂时
IHostApplicationLifetime单例
IWebHostEnvironment单例
Microsoft.AspNetCore.Hosting.IStartup单例
Microsoft.AspNetCore.Hosting.IStartupFilter暂时
Microsoft.AspNetCore.Hosting.Server.IServer单例
Microsoft.AspNetCore.Http.IHttpContextFactory暂时
Microsoft.Extensions.Logging.ILogger<TCategoryName>单例
Microsoft.Extensions.Logging.ILoggerFactory单例
Microsoft.Extensions.ObjectPool.ObjectPoolProvider单例
Microsoft.Extensions.Options.IConfigureOptions<TOptions>暂时
Microsoft.Extensions.Options.IOptions<TOptions>单例
System.Diagnostics.DiagnosticSource单例
System.Diagnostics.DiagnosticListener单例

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/csharp/aspnetcoremvc/14602.html

(0)
上一篇 2022年4月4日 00:17
下一篇 2022年5月2日 01:17

相关推荐

  • 5.ASP.NET Core MVC视图

    1.创建视图 右键单击Views文件夹-添加–新建文件夹-名称复数Movies。 右键单击刚刚新建的Views/Movies文件夹-添加–新建项-选择合适的视图选项-名称Index.cshtml–添加。 2.View()帮助方法 2.1视图发现 3.强类型数据 (viewmodel)…

  • 6.ASP.NET Core MVC标记帮助程序

    1.标记帮助程序 1.1@addTagHelper指令 @addTagHelper 指令指定程序集中要加载的标记帮助程序对于 Views 目录或子目录中的所有视图文件均可用。 @addTagHelper 后第一个参数指定程序集中要加载的的标记帮助程序的范围,第二个参数指定包含标记帮助程序的程序集。 …

  • 4.ASP.NET Core MVC控制器

    右键单击Controllers文件夹-添加–控制器。 单击MVC–控制器-选择合适的脚手架选项–添加-名称复数MoviesController.cs–添加。

发表评论

登录后才能评论