CRUD .NET Core e DynamoDB
Bom pessoal, estou de volta com a série de artigos .NET Core e AWS. No artigo de hoje faremos acesso ao banco noSQL DynamoDB da AWS.
Apesar de ser iniciante em .Net (e ainda cometer erros), já sei o suficiente para compartilhar o que estou aprendendo com vocês. 🙂
Caso queira ler o artigo anterior, acesse o link abaixo:
DynamoDB
Não vou entrar em detalhes sobre o DynamoDB, mas se você quiser mais informações sobre ele, acesse esse link.
Se isso não for suficiente, a edX está oferecendo um curso totalmente gratuito de DynamoDB. Acesse o post abaixo e veja como se inscrever.
Também existe um guia muito bom que você pode utilizar:
Se você estudar qualquer um dos materiais citados, já estará apto para acompanhar este artigo ! 🙂
Vamos agora continuar e criar o nosso banco DynamoDB na AWS.
Acesse sua conta da AWS, clique em Serviços e procure por DynamoDB.
Clique em Create Table.
Chamaremos a nossa tabela de ProductList.
Clique no botão Criar.
Faça a inserção dos dados no DynamoDb.
Agora já temos o suficiente para testar. Abra o Visual Studio e vamos iniciar o nosso projeto.
Clique em Create a new project e escolha o template ASP.Net Core Web Application.
Vamos chamar o nosso projeto de AWSProductListDynamoDb.
Agora escolha Empty, pois vamos escrever na mão as classes. Clique em Create para criar o nosso projeto.
Vamos instalar o pacote com o SDK da AWS. Para isso, acesse o Package Manager Console em View >> Other Windows >> Package Manager Console.
Digite no Package Manager Console: install-package AWSSDK.Extensions.NETCore.Setup
Verifique se a instalação ocorreu sem erros.
Agora iremos instalar o nuget do DynamoDB. Para isso, digite install-package AWSSDK.DynamoDBv2.
Verifique se a instalação ocorreu sem erros:
Agora vamos começar a implementar as classes que farão todas as operações básicas com o banco de dados:
- Criação da tabela
- Inserção de dados
- Leitura de dados
- Exclusão de dados
Primeiramente, vamos criar o nosso arquivo appsettings.json que conterá as informações necessárias para conexão com o DynamoDB na AWS e também alguns parâmetros referentes a tabela. Os principais para são:
- Region
- AccessKey
- SecretKey
{
"AWS": {
"Region": "sa-east-1",
"AccessKey": "XXXXXXXXXXXXXXXXXXX",
"SecretKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
"VAR": {
"TableName": "ProductList"
}
}
Dica: Para descobrir o Region onde o seu serviço está executando, no painel da AWS, clique na região e a nomenclatura aparecerá:
Agora vamos ao IAM (Identity Access Management) para criar o nosso usuário de acesso ao DynamoDB e assim gerar o AccessKey e o SecretKey. Para isso acesse USUÁRIOS e clique no botão adicionar usuário.
Vamos dar o nome de nosso usuário de test_dyn, e o tipo de acesso será o programático.
Para simplificar, vamos anexar as políticas de forma direta, como na imagem a seguir. A política de permissão que daremos ao nosso usuário é a AmazonDynamoDBFullAccess. Como o objetivo desse artigo não é a criação de grupos e usuários, faremos do jeito mais simples.
Vamos pular a parte de tags e ir direto a Revisão. Verifique se está tudo Ok e clique em Criar usuário.
Pronto, agora obtemos o AccessKey e o SecretKey para acessarmos o nosso banco de dados.
Agora que já temos o nosso usuário de acesso, e as chaves, vamos voltar ao nosso projeto.
Crie um novo Projeto do tipo Class Library (.NET Core) chamado AWSProductListDynamoDb. Aqui ficará todas as interfaces e classes responsáveis pelo CRUD.
Clique com o botão direito e depois em Add Reference. Selecione AWSProductListDynamoDb.Libs e clique em OK. Assim o nosso projeto principal terá acesso a todas as classes de nossa Lib.
Agora, vamos instalar o pacote do DynamoDB no segundo projeto.
PM> install-package AWSSDK.DynamoDBv2
Restoring packages for C:\Users\gioth\source\repos\AWSProductListDynamoDB\AWSProductListDynamoDB.Libs\AWSProductListDynamoDb.Libs.csproj…
GET https://api.nuget.org/v3-flatcontainer/awssdk.dynamodbv2/index.json
OK https://api.nuget.org/v3-flatcontainer/awssdk.dynamodbv2/index.json 576ms
GET https://api.nuget.org/v3-flatcontainer/awssdk.dynamodbv2/3.3.104.2/awssdk.dynamodbv2.3.3.104.2.nupkg
OK https://api.nuget.org/v3-flatcontainer/awssdk.dynamodbv2/3.3.104.2/awssdk.dynamodbv2.3.3.104.2.nupkg 14ms
GET https://api.nuget.org/v3-flatcontainer/awssdk.core/index.json
OK https://api.nuget.org/v3-flatcontainer/awssdk.core/index.json 566ms
GET https://api.nuget.org/v3-flatcontainer/awssdk.core/3.3.104/awssdk.core.3.3.104.nupkg
OK https://api.nuget.org/v3-flatcontainer/awssdk.core/3.3.104/awssdk.core.3.3.104.nupkg 10ms
Installing AWSSDK.Core 3.3.104.
Installing AWSSDK.DynamoDBv2 3.3.104.2.
Installing NuGet package AWSSDK.DynamoDBv2 3.3.104.2.
Committing restore…
Generating MSBuild file C:\Users\gioth\source\repos\AWSProductListDynamoDB\AWSProductListDynamoDB.Libs\obj\AWSProductListDynamoDb.Libs.csproj.nuget.g.props.
Writing assets file to disk. Path: C:\Users\gioth\source\repos\AWSProductListDynamoDB\AWSProductListDynamoDB.Libs\obj\project.assets.json
Restore completed in 3,36 sec for C:\Users\gioth\source\repos\AWSProductListDynamoDB\AWSProductListDynamoDB.Libs\AWSProductListDynamoDb.Libs.csproj.
Successfully installed 'AWSSDK.Core 3.3.104' to AWSProductListDynamoDb.Libs
Successfully installed 'AWSSDK.DynamoDBv2 3.3.104.2' to AWSProductListDynamoDb.Libs
Committing restore…
Assets file has not changed. Skipping assets file writing. Path: C:\Users\gioth\source\repos\AWSProductListDynamoDB\AWSProductListDynamoDB\obj\project.assets.json
Restore completed in 19,77 ms for C:\Users\gioth\source\repos\AWSProductListDynamoDB\AWSProductListDynamoDB\AWSProductListDynamoDb.csproj.
NuGet Config files used:
C:\Users\gioth\AppData\Roaming\NuGet\NuGet.Config
C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config
C:\Program Files (x86)\NuGet\Config\Xamarin.Offline.config
Feeds used:
https://api.nuget.org/v3/index.json
C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
Executing nuget actions took 357,9 ms
Time Elapsed: 00:00:05.5700886
PM>
Nosso ambiente agora está pronto ! Vamos começar a implementar o nosso CRUD.
No projeto .Net Core teremos:
AWSProductListDynamoDB – Startup.cs
using System;
using System.IO;
using Amazon.DynamoDBv2;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using AWSProductListDynamoDb.Libs.AWSProductListDynamoDb;
namespace AWSProductListDynamoDb
{
public class Startup
{
public Startup()
{
Configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
}
public IConfigurationRoot Configuration { get; set; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore();
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
Environment.SetEnvironmentVariable("AWS_ACCESS_KEY_ID",Configuration["AWS:AccessKey"]);
Environment.SetEnvironmentVariable("AWS_SECRET_ACCESS_KEY",Configuration["AWS:SecretKey"]);
Environment.SetEnvironmentVariable("AWS_REGION", Configuration["AWS:Region"]);
Environment.SetEnvironmentVariable("AWS_CONTENT", Configuration["VAR:TableName"]);
services.AddAWSService<IAmazonDynamoDB>();
services.AddSingleton<IAWSProductListDynamoDbExamples, AWSProductListDynamoDbExamples>();
services.AddSingleton<IInsertItem, InsertItem>();
services.AddSingleton<IQueryItem, QueryItem>();
services.AddSingleton<IDeleteItem, DeleteItem>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}");
});
}
}
}
AWSProductListDynamoDB – Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace AWSProductListDynamoDb
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
AWSProductListDynamoDB – Controllers – AWSProductListDynamoDb.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AWSProductListDynamoDb.Libs.AWSProductListDynamoDb;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace AWSProductListDynamoDb.Controllers
{
[Produces("application/json")]
[Route("api/[controller]")]
public class AWSProductListDynamoDBController : Controller //Base
{
private readonly IAWSProductListDynamoDbExamples _dynamoDbExamples;
private readonly IInsertItem _insertItem;
private readonly IQueryItem _queryItem;
private readonly IDeleteItem _deleteItem;
public AWSProductListDynamoDBController(IAWSProductListDynamoDbExamples dynamoDbExamples, IInsertItem insertItem, IQueryItem queryItem, IDeleteItem deleteItem)
{
_dynamoDbExamples = dynamoDbExamples;
_insertItem = insertItem;
_queryItem = queryItem;
_deleteItem = deleteItem;
}
[Route("createtable")]
public IActionResult CreateDynamoDbTable()
{
_dynamoDbExamples.CreateDynamoDbTable();
return Ok();
}
[HttpPost]
[Route("insertitem")]
public IActionResult InsertItem([FromQuery] string productName, int productQuantity)
{
_insertItem.AddNewEntry(productName, productQuantity);
return Ok();
}
[HttpGet]
[Route("queryitems")]
public async Task<IActionResult> GetItems([FromQuery] string productName)
{
var response = await _queryItem.GetItems(productName);
return Ok(response);
}
[HttpDelete]
[Route("deleteitems")]
public IActionResult DeleteItems([FromQuery] string productName)
{
_deleteItem.DeleteEntry(productName);
return Ok();
}
}
}
O projeto Lib teremos:
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – IAWSProductListDynamoDbExamples.cs (Interface)
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public interface IAWSProductListDynamoDbExamples
{
void CreateDynamoDbTable();
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – AWSProductListDynamoDbExamples.cs (Classe responsável pela criação da tabela no DynamoDb)
Caso a tabela não exista, ela será criada no DynamoDB.
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using System;
using System.Collections.Generic;
using System.Threading;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public class AWSProductListDynamoDbExamples : IAWSProductListDynamoDbExamples
{
private readonly IAmazonDynamoDB _dynamoDbClient;
private static readonly string tableName = Environment.GetEnvironmentVariable("AWS_CONTENT");
public AWSProductListDynamoDbExamples(IAmazonDynamoDB dynamoDbClient)
{
_dynamoDbClient = dynamoDbClient;
}
public void CreateDynamoDbTable()
{
try
{
CreateTempTable();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private async void CreateTempTable()
{
Console.WriteLine("Criando a tabela...");
var request = new CreateTableRequest
{
AttributeDefinitions = new List<AttributeDefinition>
{
new AttributeDefinition
{
AttributeName = "ProductName",
AttributeType = ScalarAttributeType.S //String
},
new AttributeDefinition
{
AttributeName = "ProductQuantity",
AttributeType = ScalarAttributeType.N //Number
}
},
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement
{
AttributeName = "ProductName",
KeyType = "HASH"
},
new KeySchemaElement
{
AttributeName = "ProductQuantity",
KeyType = "RANGE"
}
},
ProvisionedThroughput = new ProvisionedThroughput
{
ReadCapacityUnits = 5,
WriteCapacityUnits = 5
},
TableName = tableName
};
await _dynamoDbClient.CreateTableAsync(request);
WaitUntilTableReady(tableName);
}
public void WaitUntilTableReady(string tableName)
{
string status = null;
do
{
Thread.Sleep(5000);
try
{
var res = _dynamoDbClient.DescribeTableAsync(tableName);
status = res.Result.Table.TableStatus;
}
catch (ResourceNotFoundException)
{
Console.WriteLine(status);
}
} while (status != "ACTIVE");
{
Console.WriteLine("Tabela criada com sucesso !!!");
}
}
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – Models – DynamoDbTableItems.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace AWSProductListDynamoDb.Libs.Models
{
public class DynamoDbTableItems
{
public IEnumerable Items { get; set; }
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – Models – Item.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace AWSProductListDynamoDb.Libs.Models
{
public class Item
{
public string productName { get; set; }
public int productQuantity { get; set; }
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – IInsertItem.cs (Interface)
using System.Threading.Tasks;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public interface IInsertItem
{
Task AddNewEntry(string productName, int productQuantity);
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – InsertItem.cs (Insere os dados no banco de dados)
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public class InsertItem : IInsertItem
{
private static readonly string tableName = Environment.GetEnvironmentVariable("AWS_CONTENT");
private readonly IAmazonDynamoDB _dynamoDbClient;
public InsertItem(IAmazonDynamoDB dynamoDbClient)
{
_dynamoDbClient = dynamoDbClient;
}
public async Task AddNewEntry(string productName, int productQuantity)
{
try
{
var queryRequest = RequestBuilder(productName, productQuantity);
await PutItemAsync(queryRequest);
}
catch (InternalServerErrorException)
{
Console.WriteLine("Erro 1");
}
catch (ResourceNotFoundException)
{
Console.WriteLine("Erro 2");
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException.StackTrace.ToString());
}
}
private PutItemRequest RequestBuilder(string productName, int productQuantity)
{
Dictionary<string, AttributeValue> attributes = new Dictionary<string, AttributeValue>();
attributes["ProductName"] = new AttributeValue { S = productName.ToString() };
attributes["ProductQuantity"] = new AttributeValue { N = productQuantity.ToString() };
return new PutItemRequest
{
TableName = tableName,
Item = attributes
};
}
private async Task PutItemAsync(PutItemRequest request)
{
try
{
await _dynamoDbClient.PutItemAsync(request);
}
catch (Exception ex)
{
Console.WriteLine("Erro: " + ex.InnerException.StackTrace.ToString());
}
}
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – IQueryItem.cs (IInterface)
using System.Threading.Tasks;
using AWSProductListDynamoDb.Libs.Models;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public interface IQueryItem
{
Task GetItems(string? productName);
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – QueryItem.cs (Busca os dados no banco de dados)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using AWSProductListDynamoDb.Libs.Models;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public class QueryItem : IQueryItem
{
private readonly IAmazonDynamoDB _dynamoDbClient;
private static readonly string tableName = Environment.GetEnvironmentVariable("AWS_CONTENT");
public QueryItem(IAmazonDynamoDB dynamoDbClient)
{
_dynamoDbClient = dynamoDbClient;
}
public async Task<DynamoDbTableItems> GetItems(string productName)
{
var queryRequest = RequestBuilder(productName);
var result = await ScanAsync(queryRequest);
return new DynamoDbTableItems
{
Items = result.Items.Select(Map).ToList()
};
}
private Item Map(Dictionary<string, AttributeValue> result)
{
return new Item
{
productName = result["ProductName"].S,
productQuantity = Convert.ToInt32(result["ProductQuantity"].N)
};
}
private async Task<ScanResponse> ScanAsync(ScanRequest request)
{
var response = await _dynamoDbClient.ScanAsync(request);
return response;
}
private ScanRequest RequestBuilder(string? productName)
{
if (productName.Length <= 0)
{
return new ScanRequest
{
TableName = tableName
};
}
return new ScanRequest
{
TableName = tableName,
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
{
":v_ProductName", new AttributeValue { S = productName }
}
},
FilterExpression = "ProductName = :v_ProductName",
ProjectionExpression = "ProductName, ProductQuantity"
};
}
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – IUpdateItem.cs (Interface)
using System.Threading.Tasks;
using AWSProductListDynamoDb.Libs.Models;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public interface IUpdateItem
{
Task Update(string productName, int productQuantity);
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – UpdateItem.cs (Altera os dados no banco de dados)
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using AWSProductListDynamoDb.Libs.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public class UpdateItem : IUpdateItem
{
private readonly IQueryItem _queryItem;
private static readonly string tableName = Environment.GetEnvironmentVariable("AWS_CONTENT");
private readonly IAmazonDynamoDB _dynamoDbClient;
public UpdateItem(IQueryItem queryItem, IAmazonDynamoDB dynamoDbClient)
{
_queryItem = queryItem;
_dynamoDbClient = dynamoDbClient;
}
public async Task<Item> Update(string productName, int productQuantity)
{
var response = await _queryItem.GetItems(productName);
var currentQuantity = response.Items.Select(p => p.productQuantity).FirstOrDefault();
var request = RequestBuilder(productName, productQuantity, currentQuantity);
var result = await UpdateItemAsync(request);
return new Item
{
productName = result.Attributes["ProductName"].S,
productQuantity = Convert.ToInt32(result.Attributes["ProductQuantity"].N)
};
}
private UpdateItemRequest RequestBuilder(string productName, int productQuantity, int currentQuantity)
{
var request = new UpdateItemRequest
{
Key = new Dictionary<string, AttributeValue>
{
{
"ProductName", new AttributeValue
{
S = productName
}
}//,
//{
// "ProductQuantity", new AttributeValue
// {
// N = currentQuantity.ToString()
// }
// }
},
ExpressionAttributeNames = new Dictionary<string, string>
{
{"#P", "ProductQuantity"}
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
{
{
":newquantity", new AttributeValue
{
N = productQuantity.ToString()
}
},
{
":currquantity", new AttributeValue
{
N = currentQuantity.ToString()
}
}
},
UpdateExpression = "SET #P = :newquantity",
ConditionExpression = "#P = :currquantity",
TableName = tableName,
ReturnValues = "ALL_NEW"
};
return request;
}
private async Task<UpdateItemResponse> UpdateItemAsync(UpdateItemRequest request)
{
var response = await _dynamoDbClient.UpdateItemAsync(request);
return response;
}
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – IDeleteItem.cs (Interface)
using System.Threading.Tasks;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public interface IDeleteItem
{
Task DeleteEntry(string productName, int productQuantity);
}
}
AWSProductListDynamoDB.Libs – AWSProductListDynamoDB – DeleteItem.cs (Exclui dados do banco de dados)
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace AWSProductListDynamoDb.Libs.AWSProductListDynamoDb
{
public class DeleteItem : IDeleteItem
{
private static readonly string tableName = Environment.GetEnvironmentVariable("AWS_CONTENT");
private readonly IAmazonDynamoDB _dynamoDbClient;
public DeleteItem(IAmazonDynamoDB dynamoDbClient)
{
_dynamoDbClient = dynamoDbClient;
}
public async Task DeleteEntry(string productName, int productQuantity)
{
try
{
var queryRequest = RequestBuilder(productName, productQuantity);
await DeleteItemAsync(queryRequest);
}
catch (InternalServerErrorException)
{
Console.WriteLine("Erro 1");
}
catch (ResourceNotFoundException)
{
Console.WriteLine("Erro 2");
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException.StackTrace.ToString());
}
}
private DeleteItemRequest RequestBuilder(string productName, int productQuantity)
{
var item = new Dictionary<string, AttributeValue>
{
{"ProductName", new AttributeValue {S = productName}}
};
return new DeleteItemRequest
{
TableName = tableName,
Key = item
};
}
private async Task DeleteItemAsync(DeleteItemRequest request)
{
await _dynamoDbClient.DeleteItemAsync(request);
}
}
}
Com todas as classes criadas em nosso projeto, vamos compilá-lo ! CTRL+SHIFT+B e depois F5 para executarmos ! 🙂
Agora é hora de testarmos. Vamos abrir o postman e começar !
Primeiramente vamos inserir um novo item: 1 Motherboard
Clique em Send e veja o resultado:
Sem erros ! Vejamos agora no DynamoDb:
Agora vamos alterar a quantidade do Monitor:
Agora vamos excluir o Keyboard:
E por último, vamos pesquisar o Mouse:
É isso aí pessoal ! Espero que esse artigo seja útil a vocês !
Abraço
Fontes
A parte de “criar um novo Projeto do tipo Class Library (.NET Core) chamado AWSProductListDynamoDb” ficou muito confuso. Os nomes dos projetos se repetem e do nada é para selecionar a opção “AWSProductListDynamoDb.Libs”, que até então não foi criada.
Boa tarde Andreson ! Muito obrigado pelo retorno !
Vou analisar e fazer a correção. Valeu mesmo por chamar minha atenção a isso. 🙂
Sergio, parabéns pelo conteúdo.
Poderia disponibilizar o código completo no github? Implementei de acordo com o que está no post mas algumas interfaces não parecem estar corretas, como por exemplo no IQueryItem e QueryItem, IUpdateItem e UpdateItem.
Boa tarde Matheus !
Desculpe a demora em responder, as coisas estão bem corridas nos últimos tempos. 🙁
Vou verificar aqui sobre o código e respondo para você. Tentarei não demorar muito dessa vez.
Código no github
https://github.com/swillians/AWSProductListDynamoDB