@@ -6,27 +6,27 @@ using Microsoft.AspNetCore.Http; | |||||
using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
namespace Cap.Consistency | |||||
namespace Cap.Consistency.Store | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Provides the APIs for managing message in a persistence store. | /// Provides the APIs for managing message in a persistence store. | ||||
/// </summary> | /// </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 bool _disposed; | ||||
private readonly HttpContext _context; | private readonly HttpContext _context; | ||||
private CancellationToken CancellationToken => _context?.RequestAborted ?? CancellationToken.None; | private CancellationToken CancellationToken => _context?.RequestAborted ?? CancellationToken.None; | ||||
/// <summary> | /// <summary> | ||||
/// Constructs a new instance of <see cref="ConsistencyMessageManager{TMessage}"/>. | |||||
/// Constructs a new instance of <see cref="ConsistencyMessageManager{ConsistencyMessage}"/>. | |||||
/// </summary> | /// </summary> | ||||
/// <param name="store">The persistence store the manager will operate over.</param> | /// <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="services">The <see cref="IServiceProvider"/> used to resolve services.</param> | ||||
/// <param name="logger">The logger used to log messages, warnings and errors.</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, | IServiceProvider services, | ||||
ILogger<ConsistencyMessageManager<TMessage>> logger) { | |||||
ILogger<ConsistencyMessageManager> logger) { | |||||
if (store == null) { | if (store == null) { | ||||
throw new ArgumentNullException(nameof(store)); | throw new ArgumentNullException(nameof(store)); | ||||
} | } | ||||
@@ -43,7 +43,7 @@ namespace Cap.Consistency | |||||
/// Gets or sets the persistence store the manager operates over. | /// Gets or sets the persistence store the manager operates over. | ||||
/// </summary> | /// </summary> | ||||
/// <value>The persistence store the manager operates over.</value> | /// <value>The persistence store the manager operates over.</value> | ||||
protected internal IConsistencyMessageStore<TMessage> Store { get; set; } | |||||
protected internal IConsistencyMessageStore Store { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// Gets the <see cref="ILogger"/> used to log messages from the manager. | /// 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"/> | /// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | ||||
/// of the operation. | /// of the operation. | ||||
/// </returns> | /// </returns> | ||||
public virtual Task<OperateResult> CreateAsync(TMessage message) { | |||||
public virtual Task<OperateResult> CreateAsync(ConsistencyMessage message) { | |||||
ThrowIfDisposed(); | ThrowIfDisposed(); | ||||
//todo: validation message fileds is correct | //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"/> | /// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | ||||
/// of the operation. | /// of the operation. | ||||
/// </returns> | /// </returns> | ||||
public virtual Task<OperateResult> UpdateAsync(TMessage message) { | |||||
public virtual Task<OperateResult> UpdateAsync(ConsistencyMessage message) { | |||||
ThrowIfDisposed(); | ThrowIfDisposed(); | ||||
//todo: validation message fileds is correct | //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"/> | /// The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="OperateResult"/> | ||||
/// of the operation. | /// of the operation. | ||||
/// </returns> | /// </returns> | ||||
public virtual Task<OperateResult> DeleteAsync(TMessage message) { | |||||
public virtual Task<OperateResult> DeleteAsync(ConsistencyMessage message) { | |||||
ThrowIfDisposed(); | ThrowIfDisposed(); | ||||
if (message == null) { | if (message == null) { | ||||
@@ -111,7 +111,7 @@ namespace Cap.Consistency | |||||
/// <returns> | /// <returns> | ||||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the user matching the specified <paramref name="messageId"/> if it exists. | /// The <see cref="Task"/> that represents the asynchronous operation, containing the user matching the specified <paramref name="messageId"/> if it exists. | ||||
/// </returns> | /// </returns> | ||||
public virtual Task<TMessage> FindByIdAsync(string messageId) { | |||||
public virtual Task<ConsistencyMessage> FindByIdAsync(string messageId) { | |||||
ThrowIfDisposed(); | ThrowIfDisposed(); | ||||
return Store.FindByIdAsync(messageId, CancellationToken); | return Store.FindByIdAsync(messageId, CancellationToken); | ||||
} | } | ||||
@@ -121,9 +121,9 @@ namespace Cap.Consistency | |||||
/// </summary> | /// </summary> | ||||
/// <param name="message">The message whose identifier should be retrieved.</param> | /// <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> | /// <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(); | ThrowIfDisposed(); | ||||
return await Store.GetMessageIdAsync(message, CancellationToken); | |||||
return await Store.GeConsistencyMessageIdAsync(message, CancellationToken); | |||||
} | } | ||||
public void Dispose() { | public void Dispose() { | ||||
@@ -136,8 +136,7 @@ namespace Cap.Consistency | |||||
/// </summary> | /// </summary> | ||||
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> | /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> | ||||
protected virtual void Dispose(bool disposing) { | protected virtual void Dispose(bool disposing) { | ||||
if (disposing && !_disposed) { | |||||
Store.Dispose(); | |||||
if (disposing && !_disposed) { | |||||
_disposed = true; | _disposed = true; | ||||
} | } | ||||
} | } | ||||
@@ -1,14 +1,15 @@ | |||||
using System; | using System; | ||||
using System.Threading; | using System.Threading; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using Cap.Consistency.Infrastructure; | |||||
namespace Cap.Consistency | |||||
namespace Cap.Consistency.Store | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Provides an abstraction for a store which manages consistent message. | /// Provides an abstraction for a store which manages consistent message. | ||||
/// </summary> | /// </summary> | ||||
/// <typeparam name="TMessage"></typeparam> | |||||
public interface IConsistencyMessageStore<TMessage> : IDisposable where TMessage : class | |||||
/// <typeparam name="ConsistencyMessage"></typeparam> | |||||
public interface IConsistencyMessageStore | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Finds and returns a message, if any, who has the specified <paramref name="messageId"/>. | /// Finds and returns a message, if any, who has the specified <paramref name="messageId"/>. | ||||
@@ -18,7 +19,7 @@ namespace Cap.Consistency | |||||
/// <returns> | /// <returns> | ||||
/// The <see cref="Task"/> that represents the asynchronous operation, containing the message matching the specified <paramref name="messageId"/> if it exists. | /// The <see cref="Task"/> that represents the asynchronous operation, containing the message matching the specified <paramref name="messageId"/> if it exists. | ||||
/// </returns> | /// </returns> | ||||
Task<TMessage> FindByIdAsync(string messageId, CancellationToken cancellationToken); | |||||
Task<ConsistencyMessage> FindByIdAsync(string messageId, CancellationToken cancellationToken); | |||||
/// <summary> | /// <summary> | ||||
/// Creates a new message in a store as an asynchronous operation. | /// 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="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> | /// <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> | /// <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> | /// <summary> | ||||
/// Updates a message in a store as an asynchronous operation. | /// 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="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> | /// <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> | /// <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> | /// <summary> | ||||
/// Deletes a message from the store as an asynchronous operation. | /// 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="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> | /// <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> | /// <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> | /// <summary> | ||||
/// Gets the ID for a message from the store as an asynchronous operation. | /// 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="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> | /// <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> | /// <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; } | |||||
} | |||||
} |