Developer Docs - Developer Codex - Method Behavior Parameters ("Options")
When building a method that takes options (parameters) that change the behavior of the method, a POCO should be used instead of individual parameters. This is a recent change to our style (12/1/2021).
The reason for this is that many methods have grown over the years to include additional parameters. Because we need to maintain backwards binary compatibility that means we need to keep the old method signatures around, thus resulting in multiple methods that just call the main method. It often also leaves us with a method that has 8 or more parameters that must be passed in order to get to the one parameter you actually want.
This is cumbersome in both the method implementation as well as when calling the method.
For example, suppose you have a method called GetCampuses() and need to pass it the following parameters that alter it's behavior:
If these are all passed as parameters then we might have ended up with the following method signatures defined for our method:
GetCampuses();
GetCampuses( bool includeInactive );
GetCampuses( bool includeInactive, CampusType campusType );
GetCampuses( bool includeInactive, CampusType campusType, CampusStatus campusStatus );
Instead, we will pass a POCO that defines the options:
GetCampuses( CampusQueryOptions options = null );
class CampusQueryOptions
{
public bool IncludeInactive { get; set; }
}
However, the point is we can now add additional options to CampusQueryOptions without changing any method signatures or existing code. When adding new options a default value should be set in the POCO that maintains the desired existing functionality.
If the new option does not need to alter existing functionality then it can be simply defined with a default value that means as much. In our example above, when we add the campusType and campusStatus values, we would alter the POCO in a way to maintain that. In this case, by using nullable values:
class CampusQueryOptions
{
public bool IncludeInactive { get; set; }
public CampusType? CampusType { get; set; } = null;
public CampusStatus? CampusStatus { get; set; } = null;
}
In this particular case, a better POCO would probably be one that takes multiple campus types and statuses. It is likely that at some point we will want to set "get all campuses that are either open or pending":
class CampusQueryOptions
{
public bool IncludeInactive { get; set; }
public List CampusTypes { get; set; } = null;
public List CampusStatuses { get; set; } = null;
}
In this case, your documentation comment would be along the lines of "Limits the results to only campuses that match one of the specified values. If null or empty, then all campus types will be included."
FilterCampuses( List campuses, CampusQueryOptions options );
This new "options POCO" style does not apply across the board to every method you create. Remember that your method name should clearly indicate the intent. So if your method is a laser focused implementation that is not intended to be changed, you don't need to use a POCO (unless you are going to have a ton of parameters right off the bat). An example of this would be something like:
///
/// This method will retrieve all campuses that are currently active,
/// open and physical.
///
GetAllCurrentPhysicalCampuses( bool includeInactive = false );
Three things to note.