What is the "best way" to implement something like this:
I have a list of steps that will be iterated and ran for an IContext
instance. But, some steps will only apply to a specific instance derived from IContext
, while other steps can apply to any instance implementing IContext
.
I could create an abstract class ContextStep<TContext> : IStep
that will implement the interface and do a type check and downcast the IContext
to the generic type in Run(IContext)
, but I feel like there a better ways of doing this and I am describing an existing pattern.
Why: I want to be able to do stuff specific to a context in a step, e.g. on a DoorContext
I want to call Close()
, which is specific to the DoorContext
.
Pseudo code
interface IStep
{
void Run(IContext context);
}
IContext context = new DoorContext();
// Steps is a collection of steps, of which some should
// only be ran for a specific context implementation.
foreach (var step in steps)
{
step.Run(context);
}
Context
My program is able to analyze two types of applications. .NET Framework (FrameworkContext) and .NET Core (CoreContext). Each application has a totally different runtime behavior, therefore there are two contexts that contain information about the application: configuration, targeted runtime, etc., however, none of these are important details.
I have two use cases for this question in my application:
- The analyzing part will take part in different steps because I want it to be modular, testable, and be able to easily add steps in the future, of which these would be current steps:
EnvironmentInformation
ParseApplicationConfig (different per context)
AnalyzeEntrypoint
AnalyzeReferences
AnalyzeUnreferenced
RuntimeAvailibilityCheck (CoreContext only)
CompatibilityCheck
VersionCompatibilityCheck (different per context)
GenerateNotes (see point below)
Filter
Sort
- The application will also generate textual 'notes' (currently ~20 informative messages) about the application depending on if a condition (
ShouldGenerate(IContext context)
) on a note is applicable. One of these conditions should also be if it is a FrameworkContext or a CoreContext. For example, some messages can be generated for both contexts, but some only for one, which is very similar to the analyzing part.