bilal-fazlani / commanddotnet

A modern framework for building modern CLI apps
https://commanddotnet.bilal-fazlani.com
MIT License
570 stars 29 forks source link

Help needed to write a console app with states and data stored. #313

Closed KySpace closed 4 years ago

KySpace commented 4 years ago

I am new to writing console apps. This amazing tool is a great way for parsing and structuring commands, but if I want to store the state or data in a property, how should I do that?

I see that every time I call AppRunner.Run(), I am constructing a new instance to the app class. Is there a standard practice to let the latter command utilize the result of the former one?

Thanks!

drewburlingame commented 4 years ago

Hi @KySpace There are different approaches to this and what's best suited for your app will depend on its needs. Can you share more about what your app is doing? What commands are passing and receiving state and is the state a complex object?

KySpace commented 4 years ago

My app has the core part written in F#. I have a class (let's call it inner) that at its core, is a property that records a parsing result of a file (or a part of the file), that is not exposed to C# code. There are multiple methods that correspond to parsing and changing the state of that property, and other methods that output the part of the part of the parsing results as desired. For all these methods I want to create corresponding command methods in my C# code so that they can be called through the CLI, but where should I put the instance of that inner class that the methods belong to, and make sure the instance is not constructed every time I call one of the methods? Thanks

drewburlingame commented 4 years ago

The way console commands work is that each time you run a command, it's in a new process. Even when you pipe the result of one command to another, both commands are run in different processes.

One way around this is to serialize the state to file and deserialize it for the next command. If you want to pipe commands, then the output of the first command would be the filename.

Another way around this is to create a REPL session (read-evaluate-print-loop). An example is when you type python and enter a session. At that point, you remain within a single process while processing commands and you can share state between them.

We don't have out-of-the-box support for REPL sessions yet. We have a proof-of-concept in PR #306. You could pull the middleware classes into your app and use them to enter a session and reference the shared state.

The final option is to use Powershell or cs-script to define your commands within a shell that can store object state.

KySpace commented 4 years ago

I see. I'll give these methods a try. At least I learned a lot. Thanks!