異なるデータベースで異なるdbcontextを使用する.netコアAPIがあります。複数のdbcontextを持つスコープ付きラップされたクラス
services.AddScoped((_) => new BoundedContext(Configuration["Data:Ecommerce:ConnectionString"],
Configuration["Data:Security:ConnectionString"],
Configuration["Data:CRM:ConnectionString"]));
コントローラのアクションは1を渡し静的クラスを呼び出している:私はスコープのインスタンスとして定義されているスタートアップクラスで
public class BoundedContext : IDisposable
{
public EcommerceDbContext EcommerceContext { get; }
public SecurityDbContext SecurityContext { get; }
public CRMDbContext CrmContext { get; }
public BoundedContext(string EcommerceConnectionString,
string SecurityConnectionString,
string CRMConnectionString)
{
EcommerceContext = new EcommerceDbContext(EcommerceConnectionString);
SecurityContext = new SecurityDbContext(SecurityConnectionString);
CrmContext = new CRMDbContext(CRMConnectionString);
}
public void SaveChanges()
{
if (SecurityContext != null)
SecurityContext.SaveChanges();
if (CrmContext != null)
CrmContext.SaveChanges();
if (EcommerceContext != null)
EcommerceContext.SaveChanges();
}
public void Dispose()
{
if (SecurityContext != null)
SecurityContext.Dispose();
if (CrmContext != null)
CrmContext.Dispose();
if (EcommerceContext != null)
EcommerceContext.Dispose();
}
}
:
は、私はすべてのdbcontextsをラップするクラスを書いていますまたはいくつかの "コマンド"を使用して、このクラスがそれを実行して変更をコミットする責任を負うようにします。
namespace Test.Business.Services
{
public static class CommandService
{
static BoundedContext _context;
public static void Process(BoundedContext context, IEnumerable<ICommand> commands)
{
_context = context;
//actions
foreach (var command in commands)
{
command.Execute(_context);
}
foreach (var command in commands)
{
if (command is IBulkInsertCommand)
{
(command as IBulkInsertCommand).BulkInsert();
}
}
//commit
_context.SaveChanges();
//post actions
foreach (var command in commands)
{
if (command is IPostCommitCommand)
{
(command as IPostCommitCommand).PostCommitAction();
_context.SaveChanges();
}
}
}
}
}
私はswaggerによって生成されたsdkでこのapiを呼び出す.netコアウェブを持っています。ウェブのコントローラは、ログインしているユーザーのプロパティを取得するフィルタを持っている:
public override void OnActionExecuting(ActionExecutingContext context)
{
if (User.Identity.IsAuthenticated)
{
if (_currentUser == null)
{
_currentUser = ApiHandler.GetCurrentUser(_applicationId, _accessToken);
}
return _currentUser;
}
return null;
}
とアクションのサンプル:
// GET: /<controller>/
[HttpGet("{All}")]
public async Task<IActionResult> Index([FromRoute]string All)
{
GetNotificationResponse result = await ControllerHandler.GetNotifications(All, _accessToken());
return PartialView("~/Views/Notifications/v1/NotificationsList.cshtml",result);
}
我々はjqueryのAJAX呼び出しと、このアクションを呼び出します。問題は、 "OnActionExecuting"にSystem.ObjectDisposedExceptionが表示されることがありますが、なぜdbcontextsを管理するクラスがスコープ付きオプションで注入されているのかわかりません。
あなたはこのアーキテクチャが悪いと思うか、何か不足していますか?