Changing the behavior of MFractor's code generation and code actions
The configuration engine allows customization of MFractor to generate code specific to your project. Initially, the amount of options that are exposed will be limited but over time I will drastically increase the flexibility of MFractors code generation engine.
If you wish to have a piece of code generation customizable, please submit a feature request at MFractor Feedback.
Conceptually, MFractor has Configurables, extensible features that expose properties that can be edited by a configuration file. Configurables can be C# code actions, XML analysers, XAML code generators and much more.
When browsing this website, you may notice that parts of the site are tagged as Autogenerated. Several parts of this documentation site are autogenerated from the configurable features inside MFractor, grouping them by behaviour and categories.
Let's look at the 3 main configurable feature types:
Code actions are features exposed through the IDE context menu (accessed via
Right CLick or
Alt+Return) that fix code issues and organise, refactor and generate source code.
Code analysis features are linters that inspect for problems in your source code. Typically, code analysers are not configurable.
Code generators create source code (such as C# or XAML); they isolate the creation of a common piece of code into a single, reusable unit.
Code generators are only ever directly used by code actions; they are not exposed through the IDE.
MFractor configuration files are XML based and end with the extension
.mfc.xml; a configuration file can be named anything and be placed in any directory in a project as long as it ends in the extension
How does it work? Let's consider the following configuration file:
<?xml version="1.0" encoding="UTF-8" ?> <mfractor> <!-- Change the behaviour of the Implement View Model code action --> <configure id="com.mfractor.code_actions.xaml.implement_view_model"> <property name="BaseClass" value="MyNamespace.ViewModels.ViewModelBase"/> </configure> </mfractor>
Let's examine each of the each element in the above configuration in depth:
- We open a configuration file with the
<mfractor>tag; this is ceremony to denote to MFractor this is a config file.
- We target a configurable by using the
idattribute specifies the unique identifier of the configurable we wish to modify. An id could refer a code action, a code generator or an analysis routine.
- We modify a property using the
nameattribute specifies the configurable property we wish to edit.
valueattribute specifies the value we wish to set the property to.
- We group configurations within the
<collection name="CollectionName">element. These groups are hard coded into the product itself and relate to how the code actions, code generation and code analysis documentation folders are structured in this site.
Every element inside MFractor that can be configured has it's own unique configuration identifier. This a java-style, package based string that indicates the software, element type and element name inside the name.
For example, the Xamarin.Forms Implement View Model code action has the configuration identifier
com.mfractor.code_actions.xaml.implement_view_model. A features id is located below the heading inside the documentation:
If we wanted to change the behaviour of the Implement View Model code action, we add a
configure element into our
.mfc.xml and target the identifier
<configure id="com.mfractor.code_actions.xaml.implement_view_model"> </configure>
configure element we can now specify multiple
property tags to change properties inside the configurable.
After targeting a configurable, we can use Configurable Properties to change the behaviour of that feature.
Configurable properties are settings that can be edited on a configurable through the use of the
We place a
property tag inside a
configure tag; we can then target the property name using the
name attribute and apply a new value using the
For example, we can change the output folder for new ViewModels by using a
property setter on the
<configure id="com.mfractor.code_actions.xaml.implement_view_model"> <property name="ViewModelsFolder" value="Path/To/ViewModelsFolder"/> </configure>
Code Generation Dependencies
Often multiple code actions need to generate the same source; rather than configuring each code action separately each code action reuses a common code generator. A code generator is a configurable that encapsulates the logic needed to generate a specific piece of code.
For example, both the Implement View Model and Generate Missing Command use the Generate ICommand Implementation code generator; this allows us to set the
ICommand type once and have the behaviour propagate through all code-actions that need to generate an ICommand implementation.
This documentation site lists the code-generaton dependencies under the Uses: section.