- Prep
- Step by Step
- Notes
- Template to copy into your code to guide you through the refactoring
- 1. Call the method in question from a test
- 2. Take the 1st thing to move to async and create an
InputPipe
of it's parameters directly above it. - 3. Place a ApprovalTests to get insight into the pipeline.
- 4. Inspect result in VsCode
- 5. Add a process as a delegate
- 6. Add a collector and send input in
- 7. Process and Collect the next step in the pipeline
- 8. Delete any newly-dead code
- 9. Repeat until all code is converted
- 10. Use
GetInputs<>
to collect all the inputs and outputs in a single object: - 10. Extract a
CreatePipe()
function - 11. Move the
PipelineApprovals.Verify()
call into a unit test
- Handling multiple parameters
- Download the sample exercise
- Install the VsCode and the plugin Graphviz (dot) language support for Visual Studio Code by João Pinto
CTRL-SHIFT-V to preview a
.dot
file as a rendered graph.
Pipeline-based functions have the following stucture:
- All pipeline setup
- Then
PipelineApprovals.Verify()
- Then send input through the pipeline and extract the result.
// Set up Pipeline objects
// `PipelineApprovals.Verify()`
// Send input through pipeline
// Original code
Call the method you wish to refactor from a test. Don't think of this as a traditional unit test. Think of it more as a specialized main()
method
2. Take the 1st thing to move to async and create an InputPipe
of it's parameters directly above it.
var inputNamePipe = new InputPipe<InputType>("InputName");
Place this right in the middle of the production code you want to refactor. It is a temporary step.
PipelineApprovals.Verify(inputNamePipe);
With a DotReporter (on the test)
[UseReporter(typeof(DotReporter))]
If the code isn't in a method, use a lambda instead
var methodCallPipe = startingPoint.ProcessFunction(TheMethodCall);
var methodCallPipe = startingPoint.Process(x => x * 2);
Do this above the PipelineApprovals.Verify()
. Run it again for feedback.
var methodCallCollector = methodCallPipe.Collect();
inputNamePipe.Send(firstParameter);
var variable = methodCallCollector.SingleResult;
Previously you were using .Collect()
to pull out values from intermediate steps, but as they become unnecessary you can delete them. ReSharper is good for finding dead code.
var inputsAndOutputs = bestSandwichCollector.GetInputs<ZipCode>().AndOutputs<Sandwich>().AsTuple();
inputsAndOutputs.Send(zipCode);
inputsAndOutputs.Outputs...
var pipe = SimpleCalls.CreatePipe();
PipelineApprovals.Verify(pipe.Input1);
Every function has a single input and a single output. To use multiple input parameters, you'll have to join them into Tuple
s. If this requires new inputs, you'll need multiple InputPipe
s.