【问题标题】:.NET Core DI Child Scope with Db Context.NET Core DI 子范围和 Db 上下文
【发布时间】:2021-04-15 03:21:36
【问题描述】:

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

我想使用 .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 采用- 构造函数中的连接字符串)?

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

【问题讨论】:

  • 将需要更多上下文(详细信息)来了解您实际想要实现的目标。当前状态的问题不完整,因此不清楚,可能是XY problem
  • 你读过how to configure your DbContext吗?如果是这样,为什么这不能回答您的问题?与您想要完成的目标有何不同?
  • 我已经编辑在示例中使用 dbcontext 而不是服务。问题是已经创建了上下文。这是一个常见问题,例如,如果您在处理器方法中处理队列项,并且每个队列项的连接字符串/数据库可能不同。我无法创建多个方法,在这种情况下为每个数据库创建一个,因为队列需要一次限制为一个,因为它稍后会调用一个 powerbi 服务,该服务一次只能处理一个请求 - 所以我需要一个进程来这样做。

标签: .net-core dependency-injection


【解决方案1】:

我已经设法解决了这个问题。关键是当您使用 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));

我希望这对某人有所帮助,因为当我四处搜索时,我找不到如何做到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多