从零开始学习ASP.NET CORE(十)model和依赖注入初学习

文章介绍了在ASP.NETCORE中如何实现依赖注入,通过创建学生类和学生仓储接口,展示了如何在控制器中使用接口并进行依赖注入。在Startup类中使用AddSingleton方法进行服务注册,以确保程序的低耦合性和可测试性。文章还提到了通过扩展方法来注册服务以及在应用启动时如何在作用域内解析服务。

添加模型

1、添加学生类

public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

2、添加学生仓储接口

public interface IStudentRepository
    {
        public Student GetStudent(int id);
    }

3、添加学生仓储接口实现类
这里的构造函数是添加了多个学生的数列,然后需要实现接口GetStudent方法,获取某个id的学生的信息

public class StudentRepository : IStudentRepository
    {
        public readonly List<Student> Students;
        public StudentRepository() 
        {
            Students = new List<Student>()
            {
                new Student()
                {
                    Id = 1,
                    Name = "小胡"
                },
                new Student()
                {
                    Id = 2,
                    Name = "小吴"
                }
            };
        }
        public Student GetStudent(int id)
        {
            return Students.FirstOrDefault(s => s.Id == id);
        }
    }

control里面添加接口和方法

在构造函数中加入形参IStudentRepository _studentRepository,然后在构造函数中将参数保留在类里面,然后Index的方法用来获取最后返回的值

    public class HomeController : Controller
    {
        private readonly IStudentRepository studentRepository;
        public HomeController(IStudentRepository _studentRepository) 
        {
            studentRepository = _studentRepository;
        }
        public string Index(int id)
        {
            return studentRepository.GetStudent(id).Name;
        }
    }

添加依赖注入

直接启动

如果按照上面的所有添加完以后直接Ctrl+F5直接启动,则会有报错,承接上一篇文章,因为默认的路由‘{controller=Home}/{action=Index}/{id?}’是在Home控制器中,我们添加了接口==IStudentRepository ==但是程序里找不到这个接口实现的类在哪里,构造函数就无法输入一个实例,所以会报错。

依赖注入

此时,就需要用到依赖注入,在启动类里面的configure里面添加依赖注入,依赖注入总的有三种,今天先用AddSingleton方法,AddTranssient和AddScoped方法,后续会讲解其他三种区别,在<>中添加两个参数,前一个是接口,后一个是实现,这里讲解一下,为什么需要依赖注入,是因为,如果后续我想要改变学生仓储的一些方法,或者全部打乱重新做,我们只用更换接口是的实现类就行,不需要把原来的接口实现类改变,这样起到了不耦合的作用

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(option => option.EnableEndpointRouting = false);
            services.AddSingleton<IStudentRepository, StudentRepository>();//此行代码为依赖注入
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvcWithDefaultRoute();

            app.Run(async (content) =>
            {
                await content.Response.WriteAsync("hello world");
            });
        }
    }
结果

运行结果如下,输入不同的id可以获取不同的学生信息
在这里插入图片描述
在这里插入图片描述

补充一点,单独注册服务

可以将相关的注册组移动到扩展方法以注册服务。 例如,配置服务会被添加到以下类中:

namespace WebApplication3.DependencyInjectionText
{
    public static class MyText//名字不重要,静态类重要
    {
        public static IServiceCollection AddConfig(this IServiceCollection services, IConfiguration config)
        {
            return services;
        }

        public static IServiceCollection AddMyDependencyGroup_(this IServiceCollection services)//名字不重要,返回类型重要
        {
            services.AddSingleton<IStudentRepository, StudentRepository>();

            return services;
        }
    }
}

这样,再startup里面就可以使用这个方法,一样的效果

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMyDependencyGroup_();
        }

       ......
    }
再补充一点,如何在应用启动时限时解析范围内服务

下面是微软官网代码

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

using (var serviceScope = app.Services.CreateScope())
{
    var services = serviceScope.ServiceProvider;

    var myDependency = services.GetRequiredService<IMyDependency>();
    myDependency.WriteMessage("Call services from main");
}

app.MapGet("/", () => "Hello World!");

app.Run();

如果换成我们程序代码,我们可以改成下面的形式

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
        .ConfigureServices(service=>
            {
                service.AddScoped<IMyDependency, MyDependency>();
            });
    }
public class Startup
    {
        private readonly IServiceProvider serviceProvider_
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceProvider serviceProvider)
        {
            serviceProvider_ = serviceProvider;
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ....

            using (var serviceScope = serviceProvider_.CreateScope())
            {
               var services = serviceScope.ServiceProvider;

               var myDependency = services.GetRequiredService<IMyDependency>();
               myDependency.WriteMessage("Call services from main");
            }
            .....
        }
    }

总结

1、接口和实现在ASP.NET CORE用的非常多,需要熟练掌握接口和实现的意义就能理解微软底层为什么要用依赖注入
2、依赖注入可以保持程序的低耦合
3、提供了高测试性,使单元测试更加容易

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值