带有私有 NuGet 包的 Blazor 依赖项注入和 EF/DbContext

Posted

技术标签:

【中文标题】带有私有 NuGet 包的 Blazor 依赖项注入和 EF/DbContext【英文标题】:Blazor dependency injection and EF/DbContext with private NuGet packages 【发布时间】:2021-12-10 02:48:52 【问题描述】:

我正在尝试将 Blazor 项目设置为可在许多其他项目中重复使用,但我在理解 Blazor 的 DI 系统如何与 NuGet 包配合使用时遇到问题。

简而言之,我构建了一个简单的 Blazor 应用程序作为错误报告/请求的票务系统。它通过输入表单(构建为组件)收集简单信息,并通过实体框架和连接字符串(存储在 AppSettings.JSON 中)将票证上传到 SQL Server 数据库。 DbContext 通过 AddDbContextFactory 注入到票务应用的 DI 系统中。这一切都在解决方案中完美运行。

我的目标是:我想打包这个票务系统,并以最少的设置在我的其他应用程序中重复使用它。在其他应用程序中,我想重用“AddTicket”组件,它会简单地接受一些简单的报告数据并更新票务数据库。

作为测试,我在我的机器上本地将票务应用打包为 NuGet 包。我将它导入到一个单独的主机应用程序中。但是,我必须在主机应用程序中重新创建连接字符串和依赖注入(使用上下文工厂和所有内容)才能使包正常工作。

我的问题是,当我构建自己的 NuGet 包时,我不了解 Blazor 的 DI 系统是如何工作的,并且我不了解 Startup.cs 中的依赖注入与 NuGet 包中的内容的流程。

我只是一个简单的、可重用的表单和提交组件,所有 EF 和数据库逻辑都以最简单的方式内置在其中,我可以放入十几个外部项目中。

构建 NuGet 包的最佳方法是什么,这样我就不需要在这种情况下进行额外的依赖注入?如果我必须额外进入宿主应用的 DI 系统,我该如何让它尽可能简单?

【问题讨论】:

【参考方案1】:

当我创建一个具有注入的库时。在我的库中,我创建了一个静态类并为IServiceCollection 创建和扩展方法

public static class ServiceCollectionExtensions

    public static void AddBlazorSyncServer(this IServiceCollection services)
    
        services.AddScoped<ILogger, Logger<LoggingBroker>>();
        services.AddScoped<ILoggingBroker, LoggingBroker>();
        services.AddScoped<IDateTimeBroker, DateTimeBroker>();
        services.AddTransient<ISyncDatabaseBroker, SyncDatabaseBroker>();
        ...


    

注意:在我的示例中,SyncDatabaseBrokerDbContext

public partial class SyncDatabaseBroker : DbContext, ISyncDatabaseBroker

这使得用户在他们的代码库中进行设置变得更加容易。 数据库的处理方式必须稍有不同。当我想管理迁移或共享连接字符串时,我使用这种方法:

Program.cs(库消费服务器)

...
var migrationsAssembly = typeof(Program).Assembly.FullName;

builder.Services.AddDbContext<ApplicationDbContext>(
    options => options.UseSqlServer(
        connectionString,
        dbOpts => dbOpts.MigrationsAssembly(migrationsAssembly)));


builder.Services.AddDbContext<SyncDatabaseBroker>(
    options => options.UseSqlServer(
        connectionString, 
        dbOpts => dbOpts.MigrationsAssembly(migrationsAssembly)));
...

builder.Services.AddBlazorSyncServer();

然后我可以用于迁移的控制台命令:

Add-Migration InitialApplicationSchema -Context ApplicationDbContext -OutputDir Data/Migrations/Application
Add-Migration InitialSyncSchema -Context SyncDatabaseBroker -OutputDir Data/Migrations/Sync

Update-Database -Context ApplicationDbContext
Update-Database -Context SyncDatabaseBroker 

【讨论】:

谢谢,我知道这里的方法是什么了。但是,当我尝试将AddDbContextFactory 放入静态类时遇到问题,因为我需要提供Configuration.GetConnectionString()。这需要构造函数提供的配置。在我的 Blazor 项目(待打包)中,Startup.csConfigureServices(IServiceCollection services) 中的整行是:services.AddDbContextFactory&lt;TicketTrackerContext&gt;(options =&gt; options.UseSqlServer(Configuratoin.GetConnectionString("DbConnectionString"))); 如何将配置提供给静态扩展类? @atebo 作为扩展的参数或读取扩展方法中的“配置”。

以上是关于带有私有 NuGet 包的 Blazor 依赖项注入和 EF/DbContext的主要内容,如果未能解决你的问题,请参考以下文章

AzureDevops 静态网站未从私有源中找到 NuGet 包

具有相同依赖项的不同版本的 nuget 包的 azure 函数

如何在我的新CSPROJ类库中包含带有本机dll的NuGet包?

Nuget私有库搭建 打包依赖问题

私有 NuGet 服务器:请求实体太大

.NET Core 从 Github到 Nuget 持续集成部署