具有 Db 上下文的 .NET Core DI 子作用域

.NET Core DI Child Scope with Db Context

(我正在编写一个处理器来处理队列中的请求(控制台应用程序)。

我想使用.NET Core DI。

到目前为止,我的代码如下所示:

...
var connectionString = exportConfiguration.ConnectionString;

using (var scope = _serviceProvider.CreateScope())
{
   var provider = scope.ServiceProvider;
   var service = provider.GetRequiredService<MyContext>();

   service.SqlConnectionString = sqlConnectionString; // I don't think property injection on a dbcontext will work, it takes its connection string in via the constructor
}

我已经阅读了如何为对象分配参数,如上所示,但是我如何根据服务使用的所有对象中使用的连接字符串创建新的上下文(使用构造函数注入,因为这就是原因dbcontexts take - 构造函数中的连接字符串)?

(顺便说一句,我没有将我的连接字符串存储在队列中,代码从队列中下来,然后我的应用程序选择要使用的连接字符串)。

我已经设法解决了这个问题。关键是当您使用 CreateScope(),然后使用 GetRequiredService() 时,DI 系统将提供新对象。所以我只需要提供正确的信息。这就是我的代码现在的样子:

// Prior code gets information from a queue, which could be different every time.
// This needs passing as a constructor to the DbContext and possibly other information from the queue to other methods constructors
// (constructor injection not property injection)

var connectionString = queueItem.ConnectionString;

// save the connection string so the DI system (startup.cs) can pick it up
Startup.ConnectionString = connectionString;

using (var scope = _serviceProvider.CreateScope())
{
   var provider = scope.ServiceProvider;

   var service = provider.GetRequiredService<IMyService>();

   // go off and get data from the correct dbcontext / connection string
   var data = service.GetData();

   // more processing
}

/// The Service has the DbContext in its constructor:
public class MyService : IMyService {
    private DbContext _dbContext;
    public MyService(DbContext dbContext) {
        _dbContext = dbContext;
    }

    // more stuff that uses dbcontext
}

/// In startup.cs:
public static string ConnectionString {get;set;}
...
builder.Services.AddScoped<IMyService, MyService>();
builder.Services.AddScoped<DbContext>(options => options.UseSqlServer(Startup.ConnectionString));

// Also the following code will work if needed:
// Parameter1 is something that comes from the queue and could be different for each
// CreateScope()
build.Services.AddScoped<IMyOtherService>((_) => 
   new MyOtherService(Startup.Parameter1));

我希望这对某些人有所帮助,因为当我在谷歌上搜索时,我找不到如何做到这一点。