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

时间:2018-02-08 03:10:10

标签: c# dependency-injection .net-core amazon-dynamodb

目前正在为我的班级开发Web服务项目,并决定使用.NET Core和DynamodDB制作Web API。

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

我目前正在这样做:

DynamoDBContext

我从DynamoDB文档中获得了上面这段代码。我在项目中添加了public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDefaultAWSOptions(Configuration.GetAWSOptions()); services.AddAWSService<IAmazonDynamoDB>(); } 的实例。

IAmazonDynamoDB

在控制器中,我然后注入DynamoDBContext context; public ValuesController(IAmazonDynamoDB context) { this.context = new DynamoDBContext(context); } 实例,并使用它来创建IAmazonDynamoDB的实例。

有没有办法在DynamoDBContext方法中创建上下文的实例并将其添加到那里的项目中,或者我现在正在这样做的方式?

3 个答案:

答案 0 :(得分:3)

  

有没有办法在中创建上下文的实例   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>();
}

答案 1 :(得分:1)

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

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

创建一个实现接口的类

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);
    }
}

像你一样在你的Startup中注入它

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

上下文将在DI系统中传递,您可以在任意位置使用

private IDynamoDbContext<AwesomeClass> _awesomeContext;

public AwesomeDynamoDbService(IDynamoDbContext<AwesomeClass> awesomeContext)
{
    _awesomeContext= awesomeContext;
}

我遇到了类似的问题并编写了一个blog post来描述修复它的好方法!希望它分享一些亮点!

答案 2 :(得分:0)

如果您使用的是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(); 
}

在lambda函数处理程序顶部调用上述函数

代码运行时,它将自动检测依赖关系,并在要求提供DynamoDBContext时传递适当的IDynamoDBContext对象