gpt4 book ai didi

c# - 如何在不同的范围内获取同一服务接口(interface)的多个实现

转载 作者:行者123 更新时间:2023-12-05 06:58:54 26 4
gpt4 key购买 nike

我有一个 asp.net core 2.2 网络应用程序。有一个由多个类实现的接口(interface)。

services.AddTransient<IHandler, HandlerA>();
services.AddTransient<IHandler, HandlerB>();

IHandler 的每个实现都注入(inject)作用域 EF DbContext,如果相同的 DbContext 在不同线程之间共享,则将定期发生 float 异常当试图访问同一个实体时。所以我将每个处理程序放在一个单独的范围内。

using (var scope = _serviceProvider.CreateScope())
{
var handlers = scope.ServiceProvider.GetServices<IHandler>();
await Task.WhenAll(handlers.Select(async h =>
{
using var internalScope = scope.ServiceProvider.CreateScope();
var handler = internalScope.ServiceProvider
.GetServices<IHandler>()
.First(f => f.Name == h.Name);
await handler.Handle(cancellationToken);
}));
}

这个解决方案似乎可行,但我不确定它是否最佳。也许有更好的方法在不同的范围内获得同一服务接口(interface)的多个实现?

最佳答案

您不需要使用不同的 DBContext 访问同一个实体。定义服务并注入(inject)上面链接中解释的 Controller 。每个服务将通过管理器类使用相同的数据库上下文访问数据库。

您可以在寻求最佳实践时以这种方式使用服务。并使用依赖注入(inject)从 Controller 访问服务。

  1. 定义服务、域类和接口(interface)。
public class Service : Attribute 
{
}

//Domain Classes
public class Entity
{
string str {get; set;}
int numb {get; set;}
}

//DBContext
public class DbContext : IdentityDbContext
{
public DbContext(DbContextOptions<DbContext> options)
: base(options)
{

}
public DbSet<Entity> Entities { set; get; }
}

//Interfaces
interface IHandler
{
string method1(Entity entity);
int method2();
}
  1. 使用管理类实现接口(interface)
public class HandlerA: IHandler
{
private readonly DbContext _dbContext;
public HandlerA(DbContext dbContext)
{
_dbContext = dbContext;
}

string method1(Entity entity)
{
//access db or business stuff
_dbContext.Entities.Add(entity);
_dbContext.SaveChanges();
}
int method2(){}
}

public class HandlerB: IHandler
{
string method1(Entity entity)
{
//access db or business stuffs
_dbContext.Entities.Remove(entity);
_dbContext.SaveChanges();
}

int method2(){}
int method3(){}
}

//Services
[Service]
public class DoService1Stuff()
{
private readonly HandlerA _handlerA;
public DoService1Stuff(HandlerA handlerA)
{
_handlerA= handlerA;
}

//Implement your task
public Do(Entity entity)
{
_handlerA.method1(entity);
}
}
[Service]
public class DoService2Stuff()
{
private readonly HandlerB _handlerB;
public DoService2Stuff(HandlerB handlerB)
{
_handlerB= handlerB;
}

//Implement your task
public Do(Entity entity)
{
_handlerA.method1(entity);
}
}
  1. 在startup.cs中通过依赖注入(inject)注册服务
services.AddTransient<IHandler, HandlerA>();
services.AddTransient<IHandler, HandlerB>();
  1. 在 Controller 中访问服务
[HttpPost]
public async Task<IActionResult> DoStuff1([FromServicec] DoService1Stuff doService1Stuff)
{
var entity= new Entity
{
str="hello",
numb=2020;
};

return Ok(doService1Stuff.Do(entity))
}
//Implement second service as needed.

关于c# - 如何在不同的范围内获取同一服务接口(interface)的多个实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64502058/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com