我正试图通过许多其他项目建立一个可重用的Blazor项目,并且我在理解Blazor的DI系统如何与NuGet包一起工作时遇到了问题。
简而言之,我构建了一个简单的Blazor应用程序作为错误报告/请求的票务系统。它通过输入表单(作为组件构建)收集简单的信息,并通过实体框架和连接字符串(存储在AppSettings.JSON中)将票据上传到SQL Server数据库。DbContext通过AddDbContextFactory注入票务应用的DI系统。这一切都在解决方案中完美地工作。
我的目标是:我想打包这个票务系统和重用它在我的其他应用程序与最小的设置。在其他应用程序中,我想重用"addticket";组件,它将简单地接受一些简单的报告数据并更新票务数据库。
作为测试,我将票务应用程序打包为我机器上的本地NuGet包。我把它导入到一个单独的主机应用程序中。然而,我不得不在主机应用程序中重新创建连接字符串和依赖注入(包括上下文工厂和所有东西),以使包工作。
我的问题是,当我构建自己的NuGet包时,我不理解Blazor的DI系统是如何工作的,我不理解Startup.cs中依赖注入的流程,而不是NuGet包中的内容。
我只是一个简单的,可重用的表单和提交组件,所有的EF和数据库逻辑都以最简单的方式内置于其中,我可以将其放入十几个外部项目中。
在这种情况下,构建NuGet包的最好方法是什么,这样我就不需要做额外的依赖注入了?如果我必须在主机应用的DI系统中做一个额外的输入,我如何使它尽可能简单?当我创建一个具有注入的库时。在我的库中,我创建了一个静态类,并为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>();
...
}
}
注意在我的例子中,SyncDatabaseBroker
是一个DbContext
:
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