C# 在.NET内核中注入DynamoDBContext实例的最佳方法

C# 在.NET内核中注入DynamoDBContext实例的最佳方法,c#,dependency-injection,.net-core,amazon-dynamodb,C#,Dependency Injection,.net Core,Amazon Dynamodb,目前正在为我的班级做一个web服务项目,并决定使用.NETCore和DynamodDB制作一个web API 我只是好奇注入DynamoDBContext的最佳方式是什么 我现在是这样做的: public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDefaultAWSOptions(Configuration.GetAWSOptions());

目前正在为我的班级做一个web服务项目,并决定使用.NETCore和DynamodDB制作一个web API

我只是好奇注入
DynamoDBContext
的最佳方式是什么

我现在是这样做的:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
    services.AddAWSService<IAmazonDynamoDB>();
}
在控制器中,然后注入
IAmazonDynamoDB
实例,并使用该实例创建
DynamoDBContext
的实例

是否有方法在
ConfigureServices
方法中创建上下文实例并将其添加到项目中,或者我目前的做法是否正确

是否有方法在中创建上下文的实例 ConfigureServices方法并将其添加到该项目中,或者 我现在做的很好吗

虽然您的解决方案会起作用,但它有一个缺点。您没有对
DynamoDBContext
使用依赖项注入,而是通过
new
操作符在控制器构造函数中创建其实例。在单元测试代码时,您将面临一个问题,因为您无法替代
DynamoDBContext
的实现

正确的方法是在DI容器中注册
DynamoDBContext
,并让容器自己在需要时创建实例。通过这种方法,
IDynamoDBContext
被注入到
ValuesController

public class ValuesController
{
    private readonly IDynamoDBContext context;

    public ValuesController(IDynamoDBContext context)
    {
        this.context = context;
    }

    // ...
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
    services.AddAWSService<IAmazonDynamoDB>();
    services.AddTransient<IDynamoDBContext, DynamoDBContext>();
}
公共类值控制器
{
私有只读IDynamoDBContext上下文;
公共价值控制人(IDynamoDBContext上下文)
{
this.context=上下文;
}
// ...
}
public void配置服务(IServiceCollection服务)
{
services.AddMvc();
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
services.AddAWSService();
services.AddTransient();
}

基本上,您必须为DynamoDB上下文创建一个接口

public interface IDynamoDbContext<T> : IDisposable where T : class
{
    Task<T> GetByIdAsync(string id);
    Task SaveAsync(T item);
    Task DeleteByIdAsync(T item);
}
公共接口IDynamoDbContext:IDisposable其中T:class
{
任务GetByIdAsync(字符串id);
任务SaveAsync(T项);
任务DeleteByIdAsync(T项);
}
创建一个实现接口的类

public class DynamoDbContext<T> : DynamoDBContext, IDynamoDbContext<T>
    where T : class
{
    public DynamoDbContext(IAmazonDynamoDB client)
        : base(client)
    {

    }

    public async Task<T> GetByIdAsync(string id)
    {
        return await base.LoadAsync<T>(id);
    }

    public async Task SaveAsync(T item)
    {
        await base.SaveAsync(item);
    }

    public async Task DeleteByIdAsync(T item)
    {
        await base.DeleteAsync(item);
    }
}
公共类DynamoDbContext:DynamoDbContext,IDynamoDbContext
T:在哪里上课
{
公共DynamoDbContext(IAmazonDynamoDB客户端)
:基本(客户端)
{
}
公共异步任务GetByIdAsync(字符串id)
{
返回wait base.LoadAsync(id);
}
公共异步任务SaveAsync(T项)
{
wait base.SaveAsync(项);
}
公共异步任务DeleteByIdAsync(T项)
{
wait base.DeleteAsync(项);
}
}
像这样把它注入你的创业公司

var client = Configuration.GetAWSOptions().CreateServiceClient<IAmazonDynamoDB>();
services.AddScoped<IDynamoDbContext<AwesomeClass>>(provider => new DynamoDbContext<AwesomeClass>(client));
var client=Configuration.GetAWSOptions().CreateServiceClient();

如果您使用的是Lambda,那么您可以尝试使用下面的代码

在DynamoDB数据库类中,添加依赖于
IDynamoDBContext

public DynamoDbDatabase(IDynamoDBContext dynamoDbContext)
{            
    _dynamoDbContext = dynamoDbContext;                           
}
在Lambda的Function.cs中定义依赖项注入的映射

private static IServiceProvider ConfigureServices()
{
    var serviceCollection = new ServiceCollection();            
    serviceCollection.AddSingleton<IDynamoDBContext,DynamoDBContext>(p => new DynamoDBContext(new AmazonDynamoDBClient()));  
    return serviceCollection.BuildServiceProvider(); 
}
专用静态IServiceProvider配置服务()
{
var servicecolection=新servicecolection();
AddSingleton(p=>newdynamodbcontext(newamazondynamodbclient());
返回serviceCollection.BuildServiceProvider();
}
在lambda函数处理程序顶部调用上述函数


当您的代码运行时,它将自动检测依赖关系,并在请求运行的
IDynamoDBContext

时传递适当的
DynamoDBContext
对象!是的,我意识到我的解决方案没有使用依赖注入,这就是促使我在这里提出这个问题的原因。我以为我只是尝试在我的configure services方法中添加一个dynamodb上下文的单例,但我肯定做了一些不正确的事情,因为我得到了一些错误,说它不是正确实例化的或类似的东西。不管怎样,谢谢你的帮助!从中可以看出,“DynamoDBContext对象是线程安全的,所以最好每个应用程序构造一次并重用它。”。因此,上面的注册可以是
AddSingleton
而不是
AddTransient
,您如何设置表名?@Kob_24表名由模型控制。在这种情况下,模型是
item
的任何类型,类名将用作表名。如果该类用
DynamoDBTableAttribute
修饰,则其值将用作表名。
public DynamoDbDatabase(IDynamoDBContext dynamoDbContext)
{            
    _dynamoDbContext = dynamoDbContext;                           
}
private static IServiceProvider ConfigureServices()
{
    var serviceCollection = new ServiceCollection();            
    serviceCollection.AddSingleton<IDynamoDBContext,DynamoDBContext>(p => new DynamoDBContext(new AmazonDynamoDBClient()));  
    return serviceCollection.BuildServiceProvider(); 
}