Last active
February 22, 2024 22:17
-
-
Save ivarne/e12d280e7ad9936e9cff73a8c568ec08 to your computer and use it in GitHub Desktop.
Suggested ServiceResult implementation for Altinn apps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TestService | |
{ | |
public ServiceResult<string> GetResult(bool success) | |
{ | |
if (success) | |
{ | |
return "Hello, World!"; | |
} | |
else | |
{ | |
return new ServiceError | |
{ | |
Title = "An error occurred", | |
Details = "Something went wrong", | |
SuggestedStatusCode = HttpStatusCode.InternalServerError | |
}; | |
} | |
} | |
public void Test() | |
{ | |
ServiceResult<string> result = GetResult(true); | |
if (result.Success) | |
{ | |
Console.WriteLine(result.Data.ToString()); | |
} | |
else | |
{ | |
Console.WriteLine(result.Error.Title.ToString()); | |
} | |
result = GetResult(false); | |
if (result.Success) | |
{ | |
Console.WriteLine(result.Data); | |
} | |
else | |
{ | |
Console.WriteLine(result.Error.Title); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics.CodeAnalysis; | |
using System.Net; | |
namespace Altinn.App.Core.Helpers; | |
/// <summary> | |
/// A generic result object that can be used to wrap the result (or some error data) of a service call | |
/// </summary> | |
public sealed class ServiceResult<T> | |
{ | |
private ServiceResult(bool success, T? data, ServiceError? error) | |
{ | |
Success = success; | |
Data = data; | |
Error = error; | |
} | |
/// <summary> | |
/// Indicates if the result is successful or not | |
/// The private constructor ensures that it is not possible to create a ServiceResult without setting either Data or Error | |
/// </summary> | |
[MemberNotNullWhen(true, nameof(Data))] | |
[MemberNotNullWhen(false, nameof(Error))] | |
public bool Success { get; } | |
/// <summary> | |
/// The data object, if the result is successful | |
/// </summary> | |
public T? Data { get; } | |
/// <summary> | |
/// The error object, if the result is erronious | |
/// </summary> | |
public ServiceError? Error { get; } | |
/// <summary> | |
/// Because of the private constructor, this is the only way to create a new instance of ServiceResult | |
/// The imlicit cast makes it easy to just return an object of type T and have it wrapped in a ServiceResult | |
/// </summary> | |
public static implicit operator ServiceResult<T>(T data) => new ServiceResult<T>(true, data, null); | |
/// <summary> | |
/// Because of the private constructor, this is the only way to create a new instance of ServiceResult | |
/// The imlicit cast makes it easy to just return an object of type ServiceError and have it wrapped in a ServiceResult | |
/// </summary> | |
public static implicit operator ServiceResult<T>(ServiceError error) => new ServiceResult<T>(false, default, error); | |
} | |
public sealed class ServiceError | |
{ | |
public required string Title { get; init; } | |
public required string? Details { get; init; } | |
public HttpStatusCode? SuggestedStatusCode { get; init; } | |
public Dictionary<string, object>? Extentions { get; init; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment