Git Product home page Git Product logo

mhozaifaa / meteors.operationresult Goto Github PK

View Code? Open in Web Editor NEW
6.0 1.0 0.0 210 KB

Operation result powerful to handle multi statuses, Easy to user with fancy pattern, Support json convention, Wise level state with multi operation , able include collect and into (forkJoin) functionality

License: MIT License

C# 100.00%
operation-result csharp asp-net-core aspcore json response http helper extension repository

meteors.operationresult's Introduction

[Meteors] OperationResult 8.0.1

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

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 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,

meteors.operationresult's People

Contributors

mhozaifaa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

meteors.operationresult's Issues

To add

  • interceptor to Set,
  • Set method with not base
  • enable convert un body operation to any other type data
  • global body
  • OperationResult without Generic <>

Feature v6.2.1

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

  • move WithStatusCode extension to Base,

  • Append with OperationResult<>,

  • 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
  • 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 ("", [], {}) SerializerSettings

  • Global static Isbody, Global static checkin object to serialize , sme to add xtensions for oepration.

  • #7

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.