在.NET Core中注入DynamoDBContext实例的最佳方法

wjv*_*vic 1 c# dependency-injection amazon-dynamodb .net-core

目前正在为我的课程从事Web服务项目,并已决定使用.NET Core和DynamodDB创建Web API。

我只是很好奇注入的最佳方法DynamoDBContext是什么?

我目前正在这样做:

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

    services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
    services.AddAWSService<IAmazonDynamoDB>();
}
Run Code Online (Sandbox Code Playgroud)

我从DynamoDB文档中获得了这段代码。我将一个实例添加IAmazonDynamoDB到项目中。

DynamoDBContext context;
public ValuesController(IAmazonDynamoDB context)
{
    this.context = new DynamoDBContext(context);
}
Run Code Online (Sandbox Code Playgroud)

然后,在控制器中,注入IAmazonDynamoDB实例,并使用该实例创建的实例DynamoDBContext

有没有办法在该ConfigureServices方法中创建上下文实例并将其添加到那里的项目中,或者我目前正在做的方式还可以吗?

Cod*_*ler 5

有没有一种方法可以在ConfigureServices方法中创建上下文的实例并将其添加到那里的项目中,或者我目前正在做的方式还可以吗?

尽管您的解决方案可以使用,但它有一个缺点。您没有使用Dependency Injection作为对象DynamoDBContext,而是通过newoperator 在控制器构造函数中创建其实例。在进行单元测试代码时,您将遇到问题,因为您无法替代的实现DynamoDBContext

正确的方法是DynamoDBContext在DI容器中注册,并在需要时让容器本身创建一个实例。通过这种方法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>();
}
Run Code Online (Sandbox Code Playgroud)

  • 看起来像[此处的文档](https://aws.amazon.com/articles/using-amazon-dynamodb-object-persistence-framework-an-introduction/),“*DynamoDBContext 对象是线程安全的,因此每个应用程序构建一次并重用它是一个好主意。*”。所以上面的注册可以是`AddSingleton`而不是`AddTransient` (9认同)

und*_*Hao 5

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

public interface IDynamoDbContext<T> : IDisposable where T : class
{
    Task<T> GetByIdAsync(string id);
    Task SaveAsync(T item);
    Task DeleteByIdAsync(T item);
}
Run Code Online (Sandbox Code Playgroud)

创建一个实现接口的类

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样将其注入您的启动中

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

上下文将在 DI 系统中传递,您可以在您喜欢的地方使用它

private IDynamoDbContext<AwesomeClass> _awesomeContext;

public AwesomeDynamoDbService(IDynamoDbContext<AwesomeClass> awesomeContext)
{
    _awesomeContext= awesomeContext;
}
Run Code Online (Sandbox Code Playgroud)

我遇到了类似的问题,并写了一篇博客文章,描述了解决该问题的好方法!希望它能分享一些光明!