Cloud
The UpDevs SDK provides tools to make interacting with cloud services easier. Even though most of the implemented utilities are focused on
Azure, you can use AWS (through the package UpDevs.Sdk.Cloud.AWS) or any other cloud service by making your own implementation, using the
package UpDevs.Sdk.Cloud.
At the moment, table implementation is only available for Azure. To use AWS and others, create your own implementation of
UpDevs.Sdk.Cloud.Abstractions.ITable. Queues and File containers are available for both Azure and AWS.
Table
With tables, you're able to make use of methods allowing you to create, update, retrieve or remove a record. The available methods are:
| Method | Description |
|---|---|
| AddOrUpdate Signature: Task<TEntity> AddOrUpdate(TEntity entity) | Saves a new record or updates an existing one in the table. |
| AddOrUpdateInBatch Signature: Task<TEntity[]> AddOrUpdateInBatch(params TEntity[] entities) | Saves or updates several records in batch. |
| CreateTable Signature: Task CreateTable() | Creates the table in the cloud server. |
| Exists Signature: Task<bool> Exists() | Checks whether the table exists in the server. |
protected RetrieveSignature: Task<TEntity> Retrieve(string partitionKey, string rowKey) | Retrieves a record. |
protected RetrieveAllByPartitionSignature: AsyncPageable<TEntity> RetrieveAllByPartition(string partitionKey) | Retrieves all entities using the provided partition key. |
protected RemoveSignature: Task Remove(string partitionKey, string rowKey) | Removes a record. |
Since the way every record is retrieved might be different, you must implement your public methods for get and delete. Examples are provided in the code below.
To use a table we must first create our entity. For that purpose we can create our class and inherit from BaseAzureEntity:
public class HistoryItem : BaseAzureEntity
{
public HistoryItem()
{
PartitionKey = "partitionKey";
RowKey = Guid.NewGuid().ToString();
}
public string Action { get; set; }
}
Now we can create the referring table starting with the interface and then the class:
public interface IHistoryTable : ITable<HistoryItem>
{
Task<HistoryItem> Get(Guid id);
Task Delete(Guid id);
AsyncPageable<HistoryItem> GetAllCreations();
}
For the class, we must inform the connection string and the name of our table:
public class HistoryTable : BaseTable<HistoryItem>, IHistoryTable
{
public HistoryTable()
: base(
HostSettings.Configuration["AzureTableConnectionString"], // Connection string.
"history" // Table name.
) { }
public Task<HistoryItem> Get(Guid id)
{
return Retrieve("my-default-partition-key", id.ToString());
}
public Task Delete(string partitionKey, Guid id)
{
return Remove(partitionKey, id.ToString());
}
public AsyncPageable<HistoryItem> GetAllCreations()
{
return RetrieveAllByPartition("creation-partition-key");
}
}
After that, we can register our services using the interface and implementation and inject it wherever needed:
public class MyDomainService : BaseDomainService
{
private readonly IHistoryTable _historyTable;
public MyDomainService(
IServiceProvider serviceProvider,
IUnitOfWork unitOfWork,
IHistoryTable historyTable
) : base(serviceProvider, unitOfWork)
{
_historyTable = historyTable;
}
public Task<HistoryItem> GetById(Guid id)
{
return _historyTable.Get(id);
}
}
Queue
Queues allow users to send messages to queues.
| Method | Description |
|---|---|
| Send Signature: Task Send(TMessage message) | Sends a message to the queue. |
| HasNext Signature: Task<bool> HasNext() | Checks whether there's a next record. |
protected EnforceQueueExistsSignature: Task EnforceQueueExists() | Makes sure the queue exists by creating it if it doesn't. |
Usage:
public interface IPrintProcessQueue : IQueue<PrintData> { }
public class PrintProcessQueue : BaseQueue<PrintData>, IPrintProcessQueue
{
public PrintProcessQueue()
: base(
HostSettings.Configuration["AzureQueueConnectionString"], // Connection string.
"print-process" // Queue name.
) { }
}
After that, we can register our services using the interface and implementation and inject it wherever needed:
public class ReportGenerationService : BaseDomainService
{
private readonly IPrintProcessQueue _printQueue;
public ReportGenerationService(
IServiceProvider serviceProvider,
IUnitOfWork unitOfWork,
IPrintProcessQueue printQueue
) : base(serviceProvider, unitOfWork)
{
_printQueue = printQueue;
}
public async Task Print(ReportRequest data)
{
var report = await GenerateReport(data);
await _printQueue.Send(report);
}
}
Files Container
Files container provide easy access to file's storages in cloud services.
| Method | Description |
|---|---|
| Download Signature: Task<FileModel> Download(string fileName) | Downloads the specified file. |
| Upload Signature: Task<FileModel> Upload(FileInput data) | Uploads the file to the cloud container. |
| ListAll Signature: Task<FileModel[]> ListAll() | Lists all files of the current container. |
protected GetBlobClientSignature: BlobClient GetBlobClient(string blobName) | Retrieves the blob client. |
protected GetContainerClientSignature: BlobContainerClient GetContainerClient() | Retrieves the blob container client. |
Usage:
public interface IAvatarsFileContainer : IFileContainer { }
public class AvatarsFileContainer : BaseFileContainer, IAvatarsFileContainer
{
public AvatarsFileContainer()
: base(
HostSettings.Configuration["AzureFilesConnectionString"], // Connection string.
"avatars", // Container's name.
"avatars.azurewebsites.net/..." // Container's URL.
) { }
}
After that, we can register our services using the interface and implementation and inject it wherever needed:
public class UsersService : BaseDomainService
{
private readonly IAvatarsFileContainer _avatarsFileContainer;
public UsersService(
IServiceProvider serviceProvider,
IUnitOfWork unitOfWork,
IAvatarsFileContainer avatarsFileContainer
) : base(serviceProvider, unitOfWork)
{
_avatarsFileContainer = avatarsFileContainer;
}
public async Task UploadAvatar(UserAvatarData data)
{
// ...
var avatarResponse = await _avatarsFileContainer.Upload(
new FileInput
{
Content = data.Content.ToByteArray(),
Name = data.FileName
}
);
user.AvatarUrl = avatarResponse.Url;
}
}