Skip to content

Instantly share code, notes, and snippets.

@MhozaifaA
Last active January 1, 2022 19:56
Show Gist options
  • Save MhozaifaA/a4758ab979c6dd55093fcbc39cfa5795 to your computer and use it in GitHub Desktop.
Save MhozaifaA/a4758ab979c6dd55093fcbc39cfa5795 to your computer and use it in GitHub Desktop.
public sealed class _Operation
{
public static OperationResultBase Operation()
{
return new OperationResultBase();
}
public static OperationResult<T> Operation<T>()
{
return new OperationResult<T>();
}
public static OperationResult<T> SetSuccess<T>(T result)
{
return new OperationResult<T>().SetSuccess(result);
}
public static OperationResultBase SetSuccess(string message)
{
return new OperationResultBase() { Message = message, OperationResultType = OperationResultTypes.Success };
}
public static OperationResult<T> SetSuccess<T>(T result, string message)
{
return new OperationResult<T>().SetSuccess(result, message);
}
public static OperationResultBase SetFailed(string message, OperationResultTypes type = OperationResultTypes.Failed)
{
if (type != OperationResultTypes.Failed && type != OperationResultTypes.Forbidden && type != OperationResultTypes.Unauthorized)
throw new ArgumentException($"{nameof(SetFailed)} in {nameof(OperationResultBase)} take {type} should use with {OperationResultTypes.Failed}, {OperationResultTypes.Forbidden} or {OperationResultTypes.Unauthorized} .");
return new OperationResultBase() { Message = message, OperationResultType = type };
}
public static OperationResult<T> SetFailed<T>(string message, OperationResultTypes type = OperationResultTypes.Failed)
{
return new OperationResult<T>().SetFailed(message, type);
}
public static OperationResultBase SetException(Exception exception)
{
return new OperationResultBase() { Exception = exception, OperationResultType = OperationResultTypes.Exception };
}
public static OperationResult<T> SetException<T>(Exception exception)
{
return new OperationResult<T>().SetException(exception);
}
public static OperationResultBase SetContent(OperationResultTypes type, string message)
{
if (type != OperationResultTypes.Exist && type != OperationResultTypes.NotExist)
throw new ArgumentException($"Directly return {nameof(OperationResultBase)} take {type} should use with {OperationResultTypes.Exist} or {OperationResultTypes.NotExist} .");
return new OperationResultBase() { OperationResultType = type, Message = message };
}
public static OperationResult<T> SetContent<T>(OperationResultTypes type, string message)
{
return new OperationResult<T>().SetContent(type, message);
}
}
public class OperationResult<T> : OperationResultBase, IResult<T>
{
public T Result { get; set; }
public string Message { get; set; }
public OperationResultTypes OperationResultType { get; set; }
public bool IsSuccess => OperationResultType == OperationResultTypes.Success;
public bool HasException => this.OperationResultType == OperationResultTypes.Exception;
public Exception Exception { get; set; }
public string FullExceptionMessage => Exception?.ToFullException();
public bool HasCustomeStatusCode => StatusCode > 0;
public OperationResult<T> SetSuccess(T result)
{
Result = result;
OperationResultType = OperationResultTypes.Success;
return this;
}
public OperationResult<T> SetSuccess(string message)
{
Message = message;
OperationResultType = OperationResultTypes.Success;
return this;
}
public OperationResult<T> SetSuccess(T result, string message)
{
Result = result;
Message = message;
OperationResultType = OperationResultTypes.Success;
return this;
}
public OperationResult<T> SetFailed(string message, OperationResultTypes type = OperationResultTypes.Failed)
{
if (type != OperationResultTypes.Failed && type != OperationResultTypes.Forbidden && type != OperationResultTypes.Unauthorized)
throw new ArgumentException($"{nameof(SetFailed)} in {nameof(OperationResult<T>)} take {type} should use with {OperationResultTypes.Failed}, {OperationResultTypes.Forbidden} or {OperationResultTypes.Unauthorized} .");
Message = message;
OperationResultType = type;
return this;
}
public OperationResult<T> SetException(Exception exception)
{
Exception = exception;
OperationResultType = OperationResultTypes.Exception;
return this;
}
public OperationResult<T> SetContent(OperationResultTypes type, string message)
{
if (type != OperationResultTypes.Exist && type != OperationResultTypes.NotExist)
throw new ArgumentException($"Directly return {nameof(OperationResult<T>)} take {type} should use with {OperationResultTypes.Exist} or {OperationResultTypes.NotExist} .");
Message = message;
OperationResultType = type;
return this;
}
public static implicit operator OperationResult<T>((OperationResultTypes type, string message) type_message)
{
if (type_message.type != OperationResultTypes.Exist && type_message.type != OperationResultTypes.NotExist)
throw new ArgumentException($"Directly return {nameof(OperationResult<T>)} take {type_message.type} should use with {OperationResultTypes.Exist} or {OperationResultTypes.NotExist} .");
return new OperationResult<T>() { OperationResultType = type_message.type, Message = type_message.message };
}
public static implicit operator OperationResult<T>((string message, OperationResultTypes type) type_message)
{
if (type_message.type != OperationResultTypes.Failed && type_message.type != OperationResultTypes.Forbidden && type_message.type != OperationResultTypes.Unauthorized)
throw new ArgumentException($"{nameof(SetFailed)} in {nameof(OperationResult<T>)} take {type_message.type} should use with {OperationResultTypes.Failed}, {OperationResultTypes.Forbidden} or {OperationResultTypes.Unauthorized} .");
return new OperationResult<T>() { OperationResultType = type_message.type, Message = type_message.message };
}
public static implicit operator OperationResult<T>(T result)
{
return new OperationResult<T>().SetSuccess(result);
}
public static implicit operator OperationResult<T>((T result, string message) result_message)
{
return new OperationResult<T>().SetSuccess(result_message.result, result_message.message);
}
}
public class OperationResultBase
{
public string Message { get; set; }
public OperationResultTypes OperationResultType { get; set; }
public Exception Exception { get; set; }
public int? StatusCode { get; set; }
}
public static OperationResult<T> ToOperationResult<T>(this T @object)
=> new OperationResult<T>().SetSuccess(@object);
public static OperationResult<T> WithStatusCode<T>(this OperationResult<T> result, int statusCode)
{
result.StatusCode = statusCode;
return result;
}
public static JsonResult ToJsonResult<T>(this OperationResult<T> result)
{
return result.OperationResultType switch
{
OperationResultTypes.Success => result.GetValidResult(result.HasCustomeStatusCode.NestedIF<int>(result.StatusCode ?? 0, StatusCodes.Status200OK), null, true),
OperationResultTypes.Exist => result.GetValidResult(result.HasCustomeStatusCode.NestedIF<int>(result.StatusCode ?? 0, StatusCodes.Status202Accepted), result.Message),
OperationResultTypes.NotExist => result.GetValidResult(result.HasCustomeStatusCode.NestedIF<int>(result.StatusCode ?? 0, StatusCodes.Status404NotFound), result.Message),
OperationResultTypes.Failed => result.GetValidResult(result.HasCustomeStatusCode.NestedIF<int>(result.StatusCode ?? 0, StatusCodes.Status400BadRequest), result.Message),
OperationResultTypes.Forbidden => result.GetValidResult(result.HasCustomeStatusCode.NestedIF<int>(result.StatusCode ?? 0, StatusCodes.Status403Forbidden), result.Message),
OperationResultTypes.Unauthorized => result.GetValidResult(result.HasCustomeStatusCode.NestedIF<int>(result.StatusCode ?? 0, StatusCodes.Status401Unauthorized), result.Message),
OperationResultTypes.Exception => result.GetValidResult(result.HasCustomeStatusCode.NestedIF<int>(result.StatusCode ?? 0, StatusCodes.Status500InternalServerError), result.FullExceptionMessage),
_ => new JsonResult(string.Empty),
};
}
public static async Task<JsonResult> ToJsonResultAsync<T>(this Task<OperationResult<T>> result) => (await result).ToJsonResult();
private static JsonResult GetValidResult<T>(this OperationResult<T> result, int statusCode, string jsonMessage = null, bool json = false) =>
json ? new JsonResult(result.Result) { StatusCode = statusCode } :
new JsonResult(jsonMessage.IsNullOrEmpty() ? result.OperationResultType.ToString() : jsonMessage) { StatusCode = statusCode };
public static OperationResult<TResult1> Collect<TResult1>(this OperationResult<TResult1> result1)
=> (result1);
public static OperationResult<TResult> Into<TResult1, TResult>(this OperationResult<TResult1> result1,
Func<OperationResult<TResult1>, TResult> receiver)
=> result1.InOnce(receiver(result1));
private static OperationResult<TResult> InOnce<TResult1, TResult>(this OperationResult<TResult1> result1, TResult result)
=> OnePriority(result1, result);
public static async Task<OperationResult<TResult1>> CollectAsync<TResult1>(this Task<OperationResult<TResult1>> result1)
{
await Task.WhenAll(result1);
return (await result1);
}
public static async Task<OperationResult<TResult>> IntoAsync<TResult1, TResult>(this Task<OperationResult<TResult1>> result1,
Func<OperationResult<TResult1>, TResult> receiver)
=> await result1.InOnceAsync(receiver(await result1));
private static async Task<OperationResult<TResult>> InOnceAsync<TResult1, TResult>(this Task<OperationResult<TResult1>> result1, TResult result)
=> OnePriority(await result1, result);
public static (OperationResult<TResult1> result1, OperationResult<TResult2> result2, OperationResult<TResult3> result3) Collect<TResult1, TResult2, TResult3>(this OperationResult<TResult1> result1, OperationResult<TResult2> result2, OperationResult<TResult3> result3)
=> (result1, result2, result3);
public static OperationResult<TResult> Into<TResult1, TResult2, TResult3, TResult>(this (OperationResult<TResult1> result1, OperationResult<TResult2> result2, OperationResult<TResult3> result3) results,
Func<OperationResult<TResult1>, OperationResult<TResult2>, OperationResult<TResult3>, TResult> receiver)
=> results.InOnce(receiver(results.result1, results.result2, results.result3));
private static OperationResult<TResult> InOnce<TResult1, TResult2, TResult3, TResult>(this (OperationResult<TResult1> result1, OperationResult<TResult2> result2, OperationResult<TResult3> result3) results, TResult result)
=> OncePriority(results, result);
public static async Task<(OperationResult<TResult1> result1, OperationResult<TResult2> result2, OperationResult<TResult3> result3)> CollectAsync<TResult1, TResult2, TResult3>(this Task<OperationResult<TResult1>> result1, Task<OperationResult<TResult2>> result2, Task<OperationResult<TResult3>> result3)
{
await Task.WhenAll(result1, result2, result3);
return (await result1, await result2, await result3);
}
public static async Task<OperationResult<TResult>> IntoAsync<TResult1, TResult2, TResult3, TResult>(this Task<(OperationResult<TResult1> result1, OperationResult<TResult2> result2, OperationResult<TResult3> result3)> results,
Func<OperationResult<TResult1>, OperationResult<TResult2>, OperationResult<TResult3>, TResult> receiver)
{ var (result1, result2, result3) = await results; return await results.InOnceAsync(receiver(result1, result2, result3)); }
private static async Task<OperationResult<TResult>> InOnceAsync<TResult1, TResult2, TResult3, TResult>(this Task<(OperationResult<TResult1> result1, OperationResult<TResult2> result2, OperationResult<TResult3> result3)> results, TResult result)
=> OncePriority(await results, result);
private static OperationResult<TResult> OnePriority<TOneResult, TResult>(TOneResult oneResult, TResult result)
{
OperationResult<TResult> operation = new();
OperationResultBase Result = oneResult as OperationResultBase;
if (Result.OperationResultType == OperationResultTypes.Exception)
return operation.SetException(Result.Exception);
if (Result.OperationResultType == OperationResultTypes.Failed || Result.OperationResultType == OperationResultTypes.Forbidden || Result.OperationResultType == OperationResultTypes.Unauthorized)
return operation.SetFailed(String.Join(",",
Result.Message.IsNullOrEmpty().NestedIF($"Result {1} not contain Message or Success", Result.Message)), Result.OperationResultType);
return operation.SetSuccess(result, String.Join(",",
Result.Message.IsNullOrEmpty().NestedIF($"Result {1} not contain Message or Success", Result.Message)));
}
private static OperationResult<TResult> OncePriority<TTupleResult, TResult>(TTupleResult results, TResult result) where TTupleResult : ITuple
{
OperationResult<TResult> operation = new();
IEnumerable<OperationResultBase> listResult = Enumerable.Repeat(0, results.Length).Select(index => results[index]).Cast<OperationResultBase>();
OperationResultBase firstException = listResult.FirstOrDefault(result => result.OperationResultType == OperationResultTypes.Exception);
if (firstException != null)
return operation.SetException(firstException.Exception);
if (listResult.Any(result => result.OperationResultType == OperationResultTypes.Failed || result.OperationResultType == OperationResultTypes.Forbidden || result.OperationResultType == OperationResultTypes.Unauthorized))
return operation.SetFailed(String.Join(",",
listResult.Select((result, iter) => result.Message.IsNullOrEmpty().NestedIF($"Result {iter} not contain Message or Success", result.Message))), listResult.Max(result => result.OperationResultType));
return operation.SetSuccess(result, String.Join(",",
listResult.Select((result, iter) => result.Message.IsNullOrEmpty().NestedIF($"Result {iter} not contain Message or Success", result.Message))));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment