@@ -6,27 +6,27 @@ using Microsoft.AspNetCore.Http; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Logging; | |||
namespace Cap.Consistency | |||
namespace Cap.Consistency.Store | |||
{ | |||
/// <summary> | |||
/// Provides the APIs for managing message in a persistence store. | |||
/// </summary> | |||
/// <typeparam name="TMessage">The type encapsulating a message.</typeparam> | |||
public class ConsistencyMessageManager<TMessage> : IDisposable where TMessage : ConsistencyMessage | |||
/// <typeparam name="ConsistencyMessage">The type encapsulating a message.</typeparam> | |||
public class ConsistencyMessageManager: IDisposable | |||
{ | |||
private bool _disposed; | |||
private readonly HttpContext _context; | |||
private CancellationToken CancellationToken => _context?.RequestAborted ?? CancellationToken.None; | |||
/// <summary> | |||
/// Constructs a new instance of <see cref="ConsistencyMessageManager{TMessage}"/>. | |||
/// Constructs a new instance of <see cref="ConsistencyMessageManager{ConsistencyMessage}"/>. | |||
/// </summary> | |||
/// <param name="store">The persistence store the manager will operate over.</param> | |||
/// <param name="services">The <see cref="IServiceProvider"/> used to resolve services.</param> | |||
/// <param name="logger">The logger used to log messages, warnings and errors.</param> | |||
public ConsistencyMessageManager(IConsistencyMessageStore<TMessage> store, | |||
public ConsistencyMessageManager(IConsistencyMessageStore store, | |||
IServiceProvider services, | |||
ILogger<ConsistencyMessageManager<TMessage>> logger) { | |||
ILogger<ConsistencyMessageManager> logger) { | |||
if (store == null) { | |||
throw new ArgumentNullException(nameof(store)); | |||
} | |||
@@ -43,7 +43,7 @@ namespace Cap.Consistency | |||
/// Gets or sets the persistence store the manager operates over. | |||
/// </summary> | |||
/// <value>The persistence store the manager operates over.</value> | |||
protected internal IConsistencyMessageStore<TMessage> Store { get; set; } | |||
protected internal IConsistencyMessageStore Store { get; set; } | |||
/// <summary> | |||
/// Gets the <see cref="ILogger"/> used to log messages from the manager. | |||
@@ -61,7 +61,7 @@ namespace Cap.Consistency | |||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | |||
/// of the operation. | |||
/// </returns> | |||
public virtual Task<OperateResult> CreateAsync(TMessage message) { | |||
public virtual Task<OperateResult> CreateAsync(ConsistencyMessage message) { | |||
ThrowIfDisposed(); | |||
//todo: validation message fileds is correct | |||
@@ -79,7 +79,7 @@ namespace Cap.Consistency | |||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | |||
/// of the operation. | |||
/// </returns> | |||
public virtual Task<OperateResult> UpdateAsync(TMessage message) { | |||
public virtual Task<OperateResult> UpdateAsync(ConsistencyMessage message) { | |||
ThrowIfDisposed(); | |||
//todo: validation message fileds is correct | |||
@@ -94,7 +94,7 @@ namespace Cap.Consistency | |||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | |||
/// of the operation. | |||
/// </returns> | |||
public virtual Task<OperateResult> DeleteAsync(TMessage message) { | |||
public virtual Task<OperateResult> DeleteAsync(ConsistencyMessage message) { | |||
ThrowIfDisposed(); | |||
if (message == null) { | |||
@@ -111,7 +111,7 @@ namespace Cap.Consistency | |||
/// <returns> | |||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the user matching the specified <paramref name="messageId"/> if it exists. | |||
/// </returns> | |||
public virtual Task<TMessage> FindByIdAsync(string messageId) { | |||
public virtual Task<ConsistencyMessage> FindByIdAsync(string messageId) { | |||
ThrowIfDisposed(); | |||
return Store.FindByIdAsync(messageId, CancellationToken); | |||
} | |||
@@ -121,9 +121,9 @@ namespace Cap.Consistency | |||
/// </summary> | |||
/// <param name="message">The message whose identifier should be retrieved.</param> | |||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the identifier for the specified <paramref name="message"/>.</returns> | |||
public virtual async Task<string> GetMessageIdAsync(TMessage message) { | |||
public virtual async Task<string> GeConsistencyMessageIdAsync(ConsistencyMessage message) { | |||
ThrowIfDisposed(); | |||
return await Store.GetMessageIdAsync(message, CancellationToken); | |||
return await Store.GeConsistencyMessageIdAsync(message, CancellationToken); | |||
} | |||
public void Dispose() { | |||
@@ -136,8 +136,7 @@ namespace Cap.Consistency | |||
/// </summary> | |||
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> | |||
protected virtual void Dispose(bool disposing) { | |||
if (disposing && !_disposed) { | |||
Store.Dispose(); | |||
if (disposing && !_disposed) { | |||
_disposed = true; | |||
} | |||
} | |||
@@ -1,14 +1,15 @@ | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using Cap.Consistency.Infrastructure; | |||
namespace Cap.Consistency | |||
namespace Cap.Consistency.Store | |||
{ | |||
/// <summary> | |||
/// Provides an abstraction for a store which manages consistent message. | |||
/// </summary> | |||
/// <typeparam name="TMessage"></typeparam> | |||
public interface IConsistencyMessageStore<TMessage> : IDisposable where TMessage : class | |||
/// <typeparam name="ConsistencyMessage"></typeparam> | |||
public interface IConsistencyMessageStore | |||
{ | |||
/// <summary> | |||
/// Finds and returns a message, if any, who has the specified <paramref name="messageId"/>. | |||
@@ -18,7 +19,7 @@ namespace Cap.Consistency | |||
/// <returns> | |||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the message matching the specified <paramref name="messageId"/> if it exists. | |||
/// </returns> | |||
Task<TMessage> FindByIdAsync(string messageId, CancellationToken cancellationToken); | |||
Task<ConsistencyMessage> FindByIdAsync(string messageId, CancellationToken cancellationToken); | |||
/// <summary> | |||
/// Creates a new message in a store as an asynchronous operation. | |||
@@ -26,7 +27,7 @@ namespace Cap.Consistency | |||
/// <param name="message">The message to create in the store.</param> | |||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="OperateResult"/> of the asynchronous query.</returns> | |||
Task<OperateResult> CreateAsync(TMessage message, CancellationToken cancellationToken); | |||
Task<OperateResult> CreateAsync(ConsistencyMessage message, CancellationToken cancellationToken); | |||
/// <summary> | |||
/// Updates a message in a store as an asynchronous operation. | |||
@@ -34,7 +35,7 @@ namespace Cap.Consistency | |||
/// <param name="message">The message to update in the store.</param> | |||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="OperateResult"/> of the asynchronous query.</returns> | |||
Task<OperateResult> UpdateAsync(TMessage message, CancellationToken cancellationToken); | |||
Task<OperateResult> UpdateAsync(ConsistencyMessage message, CancellationToken cancellationToken); | |||
/// <summary> | |||
/// Deletes a message from the store as an asynchronous operation. | |||
@@ -42,7 +43,7 @@ namespace Cap.Consistency | |||
/// <param name="message">The message to delete in the store.</param> | |||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="OperateResult"/> of the asynchronous query.</returns> | |||
Task<OperateResult> DeleteAsync(TMessage message, CancellationToken cancellationToken); | |||
Task<OperateResult> DeleteAsync(ConsistencyMessage message, CancellationToken cancellationToken); | |||
/// <summary> | |||
/// Gets the ID for a message from the store as an asynchronous operation. | |||
@@ -50,6 +51,6 @@ namespace Cap.Consistency | |||
/// <param name="message">The message whose ID should be returned.</param> | |||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> | |||
/// <returns>A <see cref="Task{TResult}"/> that contains the ID of the message.</returns> | |||
Task<string> GetMessageIdAsync(TMessage message, CancellationToken cancellationToken); | |||
Task<string> GeConsistencyMessageIdAsync(ConsistencyMessage message, CancellationToken cancellationToken); | |||
} | |||
} |
@@ -0,0 +1,78 @@ | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
namespace Cap.Consistency.Store | |||
{ | |||
/// <summary> | |||
/// Represents the result of an consistent message operation. | |||
/// </summary> | |||
public class OperateResult | |||
{ | |||
// ReSharper disable once InconsistentNaming | |||
private static readonly OperateResult _success = new OperateResult { Succeeded = true }; | |||
// ReSharper disable once FieldCanBeMadeReadOnly.Local | |||
private List<OperateError> _errors = new List<OperateError>(); | |||
/// <summary> | |||
/// Flag indicating whether if the operation succeeded or not. | |||
/// </summary> | |||
public bool Succeeded { get; set; } | |||
/// <summary> | |||
/// An <see cref="IEnumerable{T}"/> of <see cref="OperateError"/>s containing an errors | |||
/// that occurred during the operation. | |||
/// </summary> | |||
/// <value>An <see cref="IEnumerable{T}"/> of <see cref="OperateError"/>s.</value> | |||
public IEnumerable<OperateError> Errors => _errors; | |||
/// <summary> | |||
/// Returns an <see cref="OperateResult"/> indicating a successful identity operation. | |||
/// </summary> | |||
/// <returns>An <see cref="OperateResult"/> indicating a successful operation.</returns> | |||
public static OperateResult Success => _success; | |||
/// <summary> | |||
/// Creates an <see cref="OperateResult"/> indicating a failed operation, with a list of <paramref name="errors"/> if applicable. | |||
/// </summary> | |||
/// <param name="errors">An optional array of <see cref="OperateError"/>s which caused the operation to fail.</param> | |||
/// <returns>An <see cref="OperateResult"/> indicating a failed operation, with a list of <paramref name="errors"/> if applicable.</returns> | |||
public static OperateResult Failed(params OperateError[] errors) { | |||
var result = new OperateResult { Succeeded = false }; | |||
if (errors != null) { | |||
result._errors.AddRange(errors); | |||
} | |||
return result; | |||
} | |||
/// <summary> | |||
/// Converts the value of the current <see cref="OperateResult"/> object to its equivalent string representation. | |||
/// </summary> | |||
/// <returns>A string representation of the current <see cref="OperateResult"/> object.</returns> | |||
/// <remarks> | |||
/// If the operation was successful the ToString() will return "Succeeded" otherwise it returned | |||
/// "Failed : " followed by a comma delimited list of error codes from its <see cref="Errors"/> collection, if any. | |||
/// </remarks> | |||
public override string ToString() { | |||
return Succeeded ? | |||
"Succeeded" : | |||
string.Format("{0} : {1}", "Failed", string.Join(",", Errors.Select(x => x.Code).ToList())); | |||
} | |||
} | |||
/// <summary> | |||
/// Encapsulates an error from the operate subsystem. | |||
/// </summary> | |||
public class OperateError | |||
{ | |||
/// <summary> | |||
/// Gets or sets ths code for this error. | |||
/// </summary> | |||
public string Code { get; set; } | |||
/// <summary> | |||
/// Gets or sets the description for this error. | |||
/// </summary> | |||
public string Description { get; set; } | |||
} | |||
} |