using BetterBusiness.AzureQueueStorage.MessageSerializer;
using Microsoft.Extensions.DependencyInjection;
namespace BetterBusiness.AzureQueueStorage.Infrastructure
{
public static class DependencyInjectionRegistry
{
public static IServiceCollection AddAzureQueueStorage(this IServiceCollection services, QueueConfig queueConfig)
{
services.AddSingleton(queueConfig);
services.AddSingleton<IMessageSerializer, JsonMessageSerializer>();
services.AddSingleton<ICloudQueueClientFactory, CloudQueueClientFactory>();
services.AddTransient<IQueueCommunicator, QueueCommunicator>();
return services;
}
}
}
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
namespace BetterBusiness.AzureQueueStorage.Infrastructure
{
public static class StringExtension
{
///
/// Compresses the string.
///
/// The text.
///
public static string ToCompressed(this string text)
{
byte[] buffer = Encoding.UTF8.GetBytes(text);
var memoryStream = new MemoryStream();
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
{
gZipStream.Write(buffer, 0, buffer.Length);
}
memoryStream.Position = 0;
var compressedData = new byte[memoryStream.Length];
memoryStream.Read(compressedData, 0, compressedData.Length);
var gZipBuffer = new byte[compressedData.Length + 4];
Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
return Convert.ToBase64String(gZipBuffer);
}
/// <summary>
/// Decompresses the string.
/// </summary>
/// <param name="compressedText">The compressed text.</param>
/// <returns></returns>
public static string ToDecompressed(this string compressedText)
{
byte[] gZipBuffer = Convert.FromBase64String(compressedText);
using (var memoryStream = new MemoryStream())
{
int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);
var buffer = new byte[dataLength];
memoryStream.Position = 0;
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
gZipStream.Read(buffer, 0, buffer.Length);
}
return Encoding.UTF8.GetString(buffer);
}
}
}
}
using Newtonsoft.Json;
namespace BetterBusiness.AzureQueueStorage.Messages
{
public abstract class BaseQueueMessage
{
[JsonIgnore]
public string Route { get; set; }
public BaseQueueMessage(string route)
{
Route = route;
}
}
}
namespace BetterBusiness.AzureQueueStorage.Messages
{
public class SendEmailCommand : BaseQueueMessage
{
public string To { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public SendEmailCommand()
: base(QueueRoutes.EmailBox)
{
}
}
}
namespace BetterBusiness.AzureQueueStorage.MessageSerializer
{
public interface IMessageSerializer
{
T Deserialize(string message);
string Serialize(object obj);
}
}
using BetterBusiness.AzureQueueStorage.Infrastructure;
using Newtonsoft.Json;
namespace BetterBusiness.AzureQueueStorage.MessageSerializer
{
public class JsonMessageSerializer : IMessageSerializer
{
public T Deserialize(string message)
{
var obj = JsonConvert.DeserializeObject(message.ToDecompressed());
return obj;
}
public string Serialize(object obj)
{
var message = JsonConvert.SerializeObject(obj);
return message.ToCompressed();
}
}
}
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue;
namespace BetterBusiness.AzureQueueStorage
{
public interface ICloudQueueClientFactory
{
CloudQueueClient GetClient();
}
public class CloudQueueClientFactory : ICloudQueueClientFactory
{
private readonly QueueConfig _queueConfig;
private CloudQueueClient _cloudQueueClient;
public CloudQueueClientFactory(QueueConfig queueConfig)
{
_queueConfig = queueConfig;
}
public CloudQueueClient GetClient()
{
if (_cloudQueueClient != null)
return _cloudQueueClient;
var storageAccount = CloudStorageAccount.Parse(_queueConfig.QueueConnectionString);
_cloudQueueClient = storageAccount.CreateCloudQueueClient();
return _cloudQueueClient;
}
}
}
using BetterBusiness.AzureQueueStorage.Messages;
using BetterBusiness.AzureQueueStorage.MessageSerializer;
using Microsoft.WindowsAzure.Storage.Queue;
using System.Threading.Tasks;
namespace BetterBusiness.AzureQueueStorage
{
public interface IQueueCommunicator
{
T Read(string message);
Task SendAsync(T obj) where T : BaseQueueMessage;
}
public class QueueCommunicator : IQueueCommunicator
{
private readonly IMessageSerializer _messageSerializer;
private readonly ICloudQueueClientFactory _cloudQueueClientFactory;
public QueueCommunicator(
IMessageSerializer messageSerializer,
ICloudQueueClientFactory cloudQueueClientFactory)
{
_messageSerializer = messageSerializer;
_cloudQueueClientFactory = cloudQueueClientFactory;
}
public T Read<T>(string message)
{
return _messageSerializer.Deserialize<T>(message);
}
public async Task SendAsync<T>(T obj) where T : BaseQueueMessage
{
var queueReference = _cloudQueueClientFactory.GetClient().GetQueueReference(obj.Route);
await queueReference.CreateIfNotExistsAsync();
var serialize = _messageSerializer.Serialize(obj);
var queueMessage = new CloudQueueMessage(serialize);
await queueReference.AddMessageAsync(queueMessage);
}
}
}
using System;
namespace BetterBusiness.AzureQueueStorage
{
public class QueueConfig
{
public string QueueConnectionString { get; set; }
public QueueConfig(string queueConnectionString)
{
if (string.IsNullOrEmpty(queueConnectionString))
throw new ArgumentException("QueueConfig.QueueConnectionString cannot be null or empty");
QueueConnectionString = queueConnectionString;
}
}
}
namespace BetterBusiness.AzureQueueStorage
{
public class QueueRoutes
{
public const string EmailBox = “email-box”;
}
}