Meteors.OperationResult 8.0.1

dotnet add package Meteors.OperationResult --version 8.0.1                
NuGet\Install-Package Meteors.OperationResult -Version 8.0.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Meteors.OperationResult" Version="8.0.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Meteors.OperationResult --version 8.0.1                
#r "nuget: Meteors.OperationResult, 8.0.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Meteors.OperationResult as a Cake Addin
#addin nuget:?package=Meteors.OperationResult&version=8.0.1

// Install Meteors.OperationResult as a Cake Tool
#tool nuget:?package=Meteors.OperationResult&version=8.0.1                

[Meteors] OperationResult 8.0.1

alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image

Meteors Operation Result came with new and redesigned to accept more than container for status and data. OperationResult is isolated but stuck with kernel of your business logic , without if/else and some corrupted code to handle results.

Install-Package Meteors.OperationResult -Version 8.0.1

<div style="display: flex;">

nuget - medium - Source Code

</div>

<p align="center"> <img width="10%" src="https://user-images.githubusercontent.com/48151918/175791394-3913f060-5551-435c-adda-5bc487964f1c.png" /> </p>

[!Important] Old enum Statues(OperationStatues) become record Statuses. See New Statues

Documentation

  • Schemas
    • OperationResult/Base Schema

      ▸ Types/Statuses

      Unknown, Success, Exist, NotExist, Failed, Forbidden, Exception, Unauthorized

      ▸ Fields/Props

      Data, IsSuccess, HasException, FullExceptionMessage, HasCutomStatusCode,Message, OperationResultType, Exception, StatusCode

      ▸ Methods/Func Helper

      SetSuccess, SetFailed, SetException, SetContent, Append, Set

      ▸ Implicit

      (type) act SetContent,

      (Tuple(type, message)) act SetContent,

      (Tuple(message,type)) act SetFailed,

      (result) act SetSuccess,

      ((result, message)) act SetSuccess,

      (exception) as SetException

      ToOperationDynamic

    • _Operation Schema

      ▸ Extensions (Abstract-Base/Main Class)

      SetSuccess, SetFailed, SetException, SetContent, Set

    • Extension Schema

      ToOperationResult<T>(), WithStatusCode<T>(statuscode:int), WithStatusCodeAsync<T>(statuscode:int), ToJsonResult<T>(), ToJsonResult<T>(body:bool), ToJsonResultAsync<T>(), ToJsonResultAsync<T>(body:bool), Collect<T1.....T7>(T2....T7), Into<T1.....T7,T>((T1....T7), CollectAsync<T1.....T7>(T2....T7), IntoAsync<T1.....T7,T>((T1....T7),

  • Use Global

//in program.cs 
OperationResultOptions.IsBody(bool)
OperationResultOptions.IntoBody(operation=> ...)
OperationResultOptions.SerializerSettings(...)
  • How to use - before get operation

      public class FooUser { UserName, Password }
      public class FooUserDetails { FullName, Age }
    
      public OperationResult<FooUserDetails> Example(FooUser user)
    

    Regular way

      {
        try
        {
          OperationResult<FooUserDetails> operation = new ();
    
          if(!IsCurrect(user))
          {
             operation.OperationResultType = OperationResultTypes.Failed;
             operation.Message = $"{user.UserName} failed to access";
            return operation;
          }
          operation.OperationResultType = OperationResultTypes.Success;
          operation.Message = $"Success to access"; //option
          operation.Data = GetDatails(user);
          return operation;
        }
        catch(Exception e)
        {
          operation.Exception = e;
          operation.OperationResultType = OperationResultTypes.Exception;
          return operation;
        }
      }
    

    Method Way

    {
      try
      {
        OperationResult<FooUserDetails> operation = new ();
    
        if(!IsCurrect(user))
        	return operation.SetFailed($"{user.UserName} failed to access");
    
        return operation.SetSuccess(result);
    
      }
      catch(Exception e)
      {
        return operation.SetException(e);
      }
    }
    

    Extension Way

    {
      try
      { 
        if(!IsCurrect(user))
        	return _Operation.SetFailed($"{user.UserName} failed to access");
    
        return _Operation.SetSuccess(result);
      }
      catch(Exception e)
      {
        return _Operation.SetException(e);
      }
    }
    

    Implicit way

    {
      try
      { 
        if(!IsCurrect(user))
        	return ($"{user.UserName} failed to access",OperationResultTypes.Failed);
    
        return result; // mean success
      }
      catch(Exception e)
      {
        return e;
      }
    }
    

    You can see benefit when using Meteors.OperationResult Ways

    With Global Exception Handle

    { 
        if(!IsCurrect(user))
        	return ($"{user.UserName} failed to access",OperationResultTypes.Failed);
        return result;
      }
    
  • How to use - After get operation

    • Most OperationResult used with WebAPIs and Responses Sync/Async :

      private IRepository repository;
      public IActionResult Index()
      {
        return repository.Example()...all controlling ...;
      }
      
      public async Task<IActionResult> Index()
      {
        return await repository.Example()...all controlling ...;
      }
      
      • ToJsonResult()

        return repository.Example().ToJsonResult();
        return await repository.Example().ToJsonResultAsync();
        
        /*
        success 200: { fullName:"Admin" , age:24 }
        other [statuscode]: "message.."
        exception: ""System.Exception. .. . .. line ... . inner exception ...""
        */
        
      • ToJsonResult(true)

        return repository.Example().ToJsonResult(isbody:true);
        return await repository.Example().ToJsonResultAsync(isbody:true);
        
        /*
        success 200: {
        "Data":{"UserName":null,"Password":null},
        "IsSuccess":true, "HasException":false,
        "FullExceptionMessage":null,"Message":"message..",
        "Status":200,"StatusCode":200
        }
        
        other [statuscode]: {
        "Data":null,
        "IsSuccess":false,"HasException":false,
        "FullExceptionMessage":null,"Message":"message..",
        "Status":[statuscode],"StatusCode":[statuscode]
        }
        
        exception: {
        "Data":null,
        "IsSuccess":false,"HasException":true,
        "FullExceptionMessage":"System.Exception. .. . .. line ... . inner exception ...","Message":"message..",
        "Status":500,"StatusCode":[statuscode]
        }
        */
        
      • WithStatusCode()

        return repository.Example().WithStatusCode(415).ToJsonResult();
        return await repository.Example().WithStatusCodeAsync(415).ToJsonResultAsync();
        
        /*
        success 415: "expected body"
        other 415: "expected body"
        exception 415: "expected body"
        */
        
      • Collect

        {
             // value: Tuple (operation1,operation3.....)
             Operation1().Collect(Operation2(),Operation3()...) 
        
               // value: Tuple (operation1,operation3.....)
             (await Operation1Async()).Collect(await Operation2Async(),await Operation3Async()...) 
        
             // value:Task Tuple ( operation1,operation3.....)
             Operation1Async().CollectAsync(Operation2Async(),Operation3Async()...) 
        
        }
        
        
      • Into see

        /*
        success[Success,Exit,NotExit] 200:  OperationResult<>(data)
        failed [Failed,Forbidden,Unauthorized] 400: "message.."
        exception 500: ""System.Exception. .. . .. line ... . inner exception ...""
        */
           Operation1().Into(o=>o) 
        
          /*
        success[Success,Exit,NotExit] 200:  OperationResult<Foo>(newdata)
        failed [Failed,Forbidden,Unauthorized] 400: "message.."
        exception 500: ""System.Exception. .. . .. line ... . inner exception ...""
        */
           Operation1().Into(o=> new Foo{  
           Result = o.Data,
             StatusMessage =  o.Status.ToString()
           }) 
        
             /* Async */
        
          Operation1Async().IntoAsync(o=>o) 
        
        
      • Collect.Into

        /*
        success[Success,Exit,NotExit] 200:  (perationResult<foo>(o1,o2)
        failed [Failed,Forbidden,Unauthorized] 400: "message.."
        exception 500: ""System.Exception. .. . .. line ... . inner exception ...""
        */
           Operation1().Collect(Operation2()).Into((o1,o2)=> new foo(){
        
             //do what want with  operation o1 
              //do what want with  operation o2
        
           }) 
        
        
             /*
        success[Success,Exit,NotExit] 200:  OperationResult<foo>(o1,o2)
        failed [Failed,Forbidden,Unauthorized] 400: "message1 + message2 + ... message7"
        exception 500: ""System.Exception. .. . .. line ... . inner exception ...""
        */
           Operation1().Collect(Operation2(),...Operation7()).Into((o1,o2....o7)=> new foo(){
        
             //do what want with  operation o1 
              //do what want with  operation o2 ...... o7
        
           }) 
        
        
             success[Success,Exit,NotExit] 200:  (OperationResult<foo>(o1,o2) , "message..","message...")
        failed [Failed,Forbidden,Unauthorized] 400: "message1 + message2 + ... message7",
        exception 500: ""System.Exception. .. . .. line ... . inner exception ...""
        */
           Operation1Async().CollectAsync(Operation2Async(),...Operation7Async()).IntoAsync((o1,o2....o7)=> new foo(){
        
             //do what want with  operation o1 
              //do what want with  operation o2 ...... o7
        
           })     
        
      • Collect.Into.ToJsonResult see

        return Operation1().Collect(Operation2(),...Operation7()).Into((o1,....o7)=>{
          new foo(){
            //fill 
          }
        }).ToJsonResult(isbody);
        return Operation1Async().CollectAsync(Operation2Async(),...Operation7Async()).IntoAsync((o1,....o7)=>{
          new foo(){
            Operation1Data = o1.Data,
            :
            Operation7Data = o7.Data
            //fill 
          }
        }).ToJsonResultAsync(isbody);
        
        /*
        isbody: false
        
        success[Success,Exit,NotExit] 200:  (OperationResult<foo>(o1,o2..o7)
        failed [Failed,Forbidden,Unauthorized] 400: "message1 + message2 + ... message7"
        exception 500: ""System.Exception. .. . .. line ... . inner exception ...""
        */
        

        /* isbody: true

        success [Success,Exit,NotExit] 200: { "Data": { "operation1Data": data1...... "operation7Data": data17} , "IsSuccess":true, "HasException":false, "FullExceptionMessage":null,"Message":"message..", "Status":200,"StatusCode":200 }

        failed [Failed,Forbidden,Unauthorized] 400: { "Data":null, "IsSuccess":false,"HasException":false, "FullExceptionMessage":null,"Message":"message1 + message2 + ... message7", "Status":[statuscode],"StatusCode":[statuscode] }

        exception: 500 { "Data":null, "IsSuccess":false,"HasException":true, "FullExceptionMessage":"System.Exception. .. . .. line ... . inner exception ...","Message":"message1 + message2 + ... message7", "Status":500,"StatusCode":[statuscode] } */

        
        
        

Guide Medium

Collect and Into extensions build to handle multi operations and choice the correct status(Priority) with new object.

How Priority works

1- Find Statuses.Exception and change status to exception.

2- Sort OperationResultTypes and join message failed (Failed, Forbidden, Unauthorized) and set status to max failed.

3- Collect message and return Result data with success status.

4- WithStatusCode after done Priority you can control with status.

**Synchronized and Asynchronized - check **Task.WhenAll


Highlighted 💻

  • move WithStatusCode extension to Base,

  • think if we replace OperationResultbase to → OperationResult without Base! as abstract (this feature allow to save same concept and add more extensions later)

  • Build interfaces for each prop, that take operation result to make once extension for interface and able to inhrent this extensions (customers build over Meteors).

  • Add ctr/method to revice all props as 'Create Instance' (more useing when you have un-know operation-prop take value after plh of condig ). ex:

      Status status;
      string message = String.Empty();
      :
      Int statuscode...
      :
    
      if(--cond--){ ..//change status } 
      else if( .... cond ---.... }....
      :
    
      _Operation.Set(status,message,statuscode....); //auto know exactly operationResult
    
  • Global static Isbody, Global static checkin object to serialize , sme to add xtensions for oepration.

  • Singletone/IEnumrable service inject to control (five 5 services as Status we have for customize).

     readonly ISuccessOperation<>  successOperation; //has custome options and custome global(scop)
     readonly IFailedOperation<>  failedOperation; //has custome options and custome global(scop)
    
  • appsettings attr.

  • IOptions for (custome default messages, handle statuscodes(->staatus)..,http,.. ).

  • HttpResponseMessage to OperationResult (support full options).

  • back to implicity (success) 😉 but for limited types (IList<>,ICollection<>,IEnumerable<>,INumber(int,double,...) .Net7.0) not supported (Tuple,Object, dynamic, any not basic) under see (string)

    OperationResult<List<Foo>> Get() 
    {  return new ();   };
    
  • Stop return null/by default value as Json like as ("", [], {})

TODO

  • implicit OperationResult<T>(T result) write doc and find other way, this cause a lot of issues 1.3
  • move some dynamic option in Extension with not able to use overread to be static controling 1.3 -> 2.0 , some while effect on prof (Test)
  • fix HasCustomeStatusCode cond inside to json result and value/ better not to mapping to json only fix internal value status>0 1.3
  • fix with not set operation types with = 0 1.3
  • linq to for in priority funcs to increase 200ns
  • enable to retuen data with other success status
  • build ToProString enum prof 1.3
  • implicti and explicti from status types to Status code ↔ 1.3 remove issue - this will not be in lib , can be extension or any spsific not fit with only 5 statuses with all statusCode of http
  • find new name for OperationResultTypes 1.3
  • warrning when use unable object in multi thread like (EF Context)
  • Helper to convert from any operation type to other with out take data (this too useful when need to get un-success to return operation from other) 'note: this will work agenst ** enable to retuen data with other success status** , later i well see how to enable two side (smart mapping can be)
  • Find more pritty way when return generic "_Operation" with out need to generic only fill *base
  • write extension methods for Http operation results, this can done by users, but Meteors is some internal using extensions of OperationResult, so they can be public and more what users need
  • Support message with SetException with all shape , look like (exception , message).

Feature [X] will braking change and effect in some features

This lib belongs to the Meteors, Meteorites helps you write less and clean code with the power of design patterns and full support for the most popular programming for perpetual projects

All you need in your project is to use meteorites, Simplicity is one in all,

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Meteors.OperationResult:

Package Downloads
MhozaifaA.ApiProxy

Package Description

Meteors.AspNetCore

Build over Asp Net Core

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
8.0.1 216 1/14/2024
8.0.0 169 12/30/2023
6.2.1 1,792 8/21/2022
6.1.6 418 6/25/2022
1.0.1 450 6/7/2022
1.0.0 414 6/7/2022