DI-Dependency Injection And EF(Entity Framework)
一 理解
1 设计原则和模式:解耦合代码,降低应用程序代码的耦合度。
程序易扩展、测试、延迟绑定;
2 编程思维
功能性类型喜欢定义成静态类,使用依赖注入,避免使用静态类,使用服务容器管理。
二 依赖注入的过程
//1 创建服务容器:ServiceCollection
IServiceCollection serviceCollection = new ServiceCollection();
//2 将定义好的类加入容器
serviceCollection.AddSingleton<Fan>();
serviceCollection.AddSingleton<IAppliance, Fan>();
//serviceCollection.AddScoped<Fan>();
//serviceCollection.AddTransient<Fan>();
//3 获取服务提供器
ServiceProvider prv = serviceCollection.BuildServiceProvider();
//4 获取服务
var fanService = prv.GetService<Fan>();
//5 调用服务方法
fanService.turnOn();
三 DI连同EF(Entity Framework)Console应用程序示例
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting.Internal; using Microsoft.Extensions.Logging; using MiniEFConsoleDemo.Data; using MiniEFConsoleDemo.Services; using MiniEFConsoleDemo.Settings.Classes; using MiniEFConsoleDemo.Settings.Services; using static System.Net.Mime.MediaTypeNames; Console.WriteLine("Hello, World!"); // 1. 构建配置 var config = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); //// 2. 注册服务 //var services = new ServiceCollection(); using var host = CreateHostBuilder(args).Build(); /* // 注册 AppDbContext到依赖注入容器 services.AddDbContext<AppDbContext>(options => { options.UseSqlServer( config.GetConnectionString("EFDBConnection"), b => b.MigrationsAssembly("MiniEFConsoleDemo") // 指定迁移程序集 ); // 可选:在控制台输出 SQL 日志 options.LogTo(Console.WriteLine, LogLevel.Information); }); // 注册业务服务 services.AddScoped<UserService>(); services.AddScoped<OrderService>(); // 注册配置 var appSet = config.GetSection("AppSettings"); services.Configure<AppSettings>(config.GetSection("AppSettings")); var environment = new HostingEnvironment { EnvironmentName = "Development", ApplicationName = "MyConsoleApp", ContentRootPath = Directory.GetCurrentDirectory() }; services.AddSingleton<IHostEnvironment>(environment); // 3. 构建服务容器 var serviceProvider = services.BuildServiceProvider(); serviceProvider.GetRequiredService<AppDbContext>(); */ var serviceProvider = host.Services; // 4. 自动创建数据库(开发环境使用)或数据库迁移 using (var scope = serviceProvider.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService<AppDbContext>(); var env = scope.ServiceProvider.GetRequiredService<IHostEnvironment>(); try { if (env.IsDevelopment()) { await context.Database.EnsureCreatedAsync(); } else { //回滚到初始状态 //相当于Update-Database 0 //await context.Database.MigrateAsync("0"); //应用所用挂起的迁移文件,如果没有迁移文件不做任何工作 //相当于 update-database await context.Database.MigrateAsync(); // 应用指定的单个迁移 //相当于 update-database 20240101000000_InitialCreate // await context.Database.MigrateAsync("20240101000000_InitialCreate"); } // 可选:验证数据库连接 if (await context.Database.CanConnectAsync()) { Console.WriteLine("数据库连接成功"); } } catch (Exception ex) { Console.WriteLine($"数据库初始化失败: {ex.Message}"); throw; } } //5.使用服务 using (var scope = serviceProvider.CreateScope()) { var userService = scope.ServiceProvider.GetRequiredService<UserService>(); var orderService = scope.ServiceProvider.GetRequiredService<OrderService>(); // 创建用户 var user = await userService.CreateUserAsync("张三", "zhangsan@example.com"); Console.WriteLine($"创建用户成功: {user.Name}, ID: {user.Id}"); // 创建订单 var order = await orderService.CreateOrderAsync(user.Id, 99.99m); Console.WriteLine($"创建订单成功: {order.OrderNumber}, 金额: {order.Amount}"); // 查询所有用户 var users = await userService.GetAllUsersAsync(); foreach (var u in users) { Console.WriteLine($"用户: {u.Name}, 邮箱: {u.Email}, 订单数: {u.Orders?.Count ?? 0}"); } } Console.WriteLine("按任意键退出..."); //Console.ReadKey(); static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { // 配置服务 var config = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); services.AddDbContext<AppDbContext>(options => { options.UseSqlServer( config.GetConnectionString("EFDBConnection"), b => b.MigrationsAssembly("MiniEFConsoleDemo") // 指定迁移程序集 ); // 可选:在控制台输出 SQL 日志 options.LogTo(Console.WriteLine, LogLevel.Information); }); // 注册业务服务 services.AddScoped<UserService>(); services.AddScoped<OrderService>(); // 注册配置 var appSet = config.GetSection("AppSettings"); services.Configure<AppSettings>(config.GetSection("AppSettings")); var environment = new HostingEnvironment { EnvironmentName = "Development", ApplicationName = "MyConsoleApp", ContentRootPath = Directory.GetCurrentDirectory() }; services.AddSingleton<IHostEnvironment>(environment); // 配置选项 services.Configure<AppSettings>(context.Configuration.GetSection("AppSettings")); }) .ConfigureLogging(logging => { logging.ClearProviders(); logging.AddConsole(); logging.AddDebug(); logging.SetMinimumLevel(LogLevel.Information); }); // 1 Read appsettings.json file to get the data. string conStr = DirectReadSettings(); // 2 Bind the appsetings class to get the data. conStr = BindSettings(); ServiceOption(); static string DirectReadSettings() { string conStr = string.Empty; var config = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) // 设置基础路径为程序运行目录 .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); // 读取单个值 conStr = config?.GetConnectionString("EFDBConnection") ?? string.Empty; Console.WriteLine($"connectionstring:{conStr}"); return conStr; } static string BindSettings() { string result = string.Empty; var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); // 方式一:直接绑定 var appSettings = configuration.GetSection("AppSettings").Get<AppSettings>(); result = appSettings?.AppName ?? string.Empty; Console.WriteLine($"AppSetting AppName-{appSettings?.AppName ?? string.Empty} AppVersion-{appSettings?.Version ?? string.Empty}"); return result; } static void ServiceOption() { var config = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) // 设置基础路径为程序运行目录 .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); // 注册服务 var services = new ServiceCollection(); services.Configure<AppSettings>(config.GetSection("AppSettings")); services.AddSingleton<MyService>(); // 构建服务 var serviceProvider = services.BuildServiceProvider(); // 解析创建服务 var myService = serviceProvider.GetRequiredService<MyService>(); serviceProvider.GetService<MyService>(); myService.Run(); }
浙公网安备 33010602011771号