Skip to main content

Dynamics 365 Finance Feature Management Developer Tips

See examples of chain of command and event handler frameworks in Dynamics 365 Finance Feature management to help developers deploy code faster.
banner background

The Feature management workspace in Microsoft Dynamics 365 Finance provides a built-in dashboard designed for system administrators and users who are assigned to the Feature manager role or the Feature viewer role. It can help these users effectively view, manage, and schedule all available release features. However, enabling and disabling features should be treated with the same care and attention as any code change to the system. In this article, we’ll cover how Dynamics 365 Finance Feature management can help developers deploy code faster with less risk.

By default, new release features are turned off. Users can choose to enable features based on their specific business needs. However, before enabling or disabling features, it’s helpful to review documentation from Microsoft. In addition, it’s important to note that features should be turned on in a pre-production environment, undergo thorough testing, and then be enabled in the production environment.

Below, we’ll show examples of the programming code needed for creating a class for features along with chain of command (CoC) and event handler frameworks for constructing logic for a feature class.

Getting Started

Open Visual Studios and create a new Finance Operations project.

Microsoft Dynamics 365 Finance Create New Project

Give the project a name, check the field details, and select Create to move on to the next step.

Microsoft Dynamics 365 Finance Configure New Project

Feature Class

In this context, a “class” is a software construct that defines the data and methods of the instances that are later constructed from that class.

In your Visual Studios project, select Class to add a new feature class.

Microsoft Dynamics 365 Finance Add New Item

Below is the framework to create a class for features in Dynamics 365 Finance. Further, this programming code can help developers prevent system administrators and users who are assigned to the Feature manager role from disabling features in the class.

// Required attributes for the class
using System.ComponentModel.Composition;
using IFeatureLifecycle = Microsoft.Dynamics.ApplicationPlatform.FeatureExposure.IFeatureLifecycle;
using IFeatureMetadata = Microsoft.Dynamics.ApplicationPlatform.FeatureExposure.IFeatureMetadata;
using FeatureLifecycleStage = Microsoft.Dynamics.ApplicationPlatform.FeatureExposure.FeatureLifecycleStage;
using PlatformStateProvider = Microsoft.Dynamics.ApplicationPlatform.FeatureExposure.FeatureStateProvider;
 
[ExportAttribute(identifierstr(Microsoft.Dynamics.ApplicationPlatform.FeatureExposure.IFeatureMetadata))]
internal class ExampleFeatureFORVIS implements IFeatureLifecycle, IFeatureMetadata
{
    private static ExampleFeatureFORVIS instance = new ExampleFeatureFORVIS ();
    public static ExampleFeatureFORVIS instance()
    {
        return instance;
    }
 
    [Hookable(false)]
    public int module()
    {
        return FeatureModuleV0::AccountsReceivable;
    }
 
    [Hookable(false)]
    public LabelId label()
    {
        return literalStr("Feature name");
    }
 
    [Hookable(false)]
    public str summary()
    {
        return literalStr("Summary of the feature to be displayed in Feature Management.");
    }
 
    [Hookable(false)]
    public WebSiteURL learnMoreUrl()
    {
        return "Website URL to learn more about the feature.";
    }
 
    [Hookable(false)]
    public boolean isEnabledByDefault()
    {
    // This controls if the feature is turned on at the time of promotion
        return false;
    }
 
    [Hookable(false)]
    public boolean canDisable()
    {
// Prevents others from disabling the feature 
        return true;
    }
 
    public FeatureLifecycleStage FeatureStage()
    {
        return FeatureLifecycleStage::PrivatePreview;
    }
 
}

Enabling/Disabling Logic Using Chain of Command

It’s important to note that developers can use CoC or event handler programming code when constructing logic for a feature class. Developers only need to implement one option. While both options can be used, CoC can help:

  • Provide more flexibility
  • Extend Microsoft’s base code more dynamically (event handler logic is static)
  • Streamline programming code for future release updates (by reducing the need to keep overlays and separate extension classes)

Microsoft has implemented CoC across classes, tables, forms, and more. In Dynamics 365 Finance, CoC can trigger logic based on whether a feature is enabled or disabled. See an example of CoC code below.

[ExtensionOf(tableStr(FeatureManagementState))]
final class FeatureManagementState_Extension
{
    public void insert()
    {
        next insert();

    if (this.Name == Dynamics.AX.Application.FeatureStateProvider::featureName(ExampleFeatureFORVIS::instance())
    && (this.IsEnabled != this.orig().isEnabled && this.IsEnabled == NoYes::Yes))
    {
//Enable Action

    }

 }
 
    public void update()
    {
        next update();

        if (this.Name == Dynamics.AX.Application.FeatureStateProvider::featureName(ExampleFeatureFORVIS::instance())
    && (this.IsEnabled != this.orig().isEnabled && this.IsEnabled == NoYes::Yes))
    {
// Enable Action
    }
    else (this.Name == Dynamics.AX.Application.FeatureStateProvider::featureName(ExampleFeatureFORVIS::instance())
    && (this.IsEnabled != this.orig().isEnabled && this.IsEnabled == NoYes::Bi))
    {
// Disable action
    }
    }
}

Enabling/Disabling Logic Using Event Handler

As noted above, developers can use CoC or event handler programming code when constructing logic for a feature class. Developers only need to implement one option. Below is an example of event handler code to trigger logic based on whether a feature is enabled or disabled.

/// <summary>
/// Execute code when feature is enabled.
/// </summary>
internal final class ExampleFeatureFORVIS_EventHandler
{
    /// <summary>
    /// Copies records to new table once enabled.
    /// datasource order when the <c>ExampleFeatureFORVIS</c>
    /// feature is inserted and defaulted to enabled.
    /// </summary>
    /// <param name="_sender">
    /// The <c>FeatureManagementState</c> record updated.
    /// </param>
    /// <param name="_args">
    /// The event arguments.
    /// </param>
    [DataEventHandler(tableStr(FeatureManagementState), DataEventType::Inserted)]
    public static void executeActionOnInserted(Common _sender, DataEventArgs _args)
    {
        FeatureManagementState featureManagementState = _sender;
 
        if (featureManagementState.Name == Dynamics.AX.Application.FeatureStateProvider::featureName(ExampleFeatureFORVIS::instance())
            && featureManagementState.IsEnabled == NoYes::Yes
            )
        {
            ExampleFeatureFORVIS_EventHandler::executeAction();
        }
    }
 
    /// <summary>
    /// Copies records to new table once enabled.
    /// order, after enabling or disabling the <c>ExampleFeatureFORVIS</c> feature.
    /// </summary>
    /// <param name="_sender">
    /// The <c>FeatureManagementState</c> record updated.
    /// </param>
    /// <param name="_args">
    /// The event arguments.
    /// </param>
    [DataEventHandler(tableStr(FeatureManagementState), DataEventType::Updated)]
    public static void executeActionOnUpdated(Common _sender, DataEventArgs _args)
    {
        FeatureManagementState featureManagementState = _sender;
 
        if (featureManagementState.Name == Dynamics.AX.Application.FeatureStateProvider::featureName(ExampleFeatureFORVIS::instance())
        && (featureManagementState.IsEnabled != featureManagementState.orig().isEnabled && featureManagementState.IsEnabled == NoYes::Yes)
            )
        {
ExampleFeatureFORVIS_EventHandler::executeAction();
        }
    else if (featureManagementState.Name == Dynamics.AX.Application.FeatureStateProvider::featureName(ExampleFeatureFORVIS::instance())
      && (featureManagementState.IsEnabled != featureManagementState.orig().isEnabled && featureManagementState.IsEnabled == NoYes::No)
{
    // Disable Feature
}

    }
 
    private static void executeAction()
    {
       
        // Do some action 
    }
 
}

Wrapping New Code to Execute Only When the Feature Is Enabled

After you’ve created and compiled your feature class code, you can invoke the following code at any point to enable the specific logic you’d like to execute.

if (FeatureStateProvider::isFeatureEnabled(ExampleFeatureFORVIS::instance()))
{
    // code you only want to execute if feature is enabled.
}

Now Available in Feature Management

To make this project accessible in the Feature management workspace, click on the Feature management tile in the Dynamics 365 Finance dashboard.

Microsoft Dynamics 365 Finance Feature Management

Once in the workspace, select “Check for updates” on the Features page to see your new feature appear. 

Microsoft Dynamics 365 Finance Feature Management Check for Updates

When ready, click “Enable now” to turn it on.

How FORVIS Can Help

The examples here can help developers deploy code faster with less risk in Dynamics 365 Finance Feature management. For more developer tips or support services, use the Contact Us form below to get in touch.

The Business Technology Solutions team at FORVIS can assist you with your business technology needs. We are a Microsoft Dynamics Gold Partner and 2022–23 recipient of the Microsoft Inner Circle Award. We provide analysis, design, implementation, upgrade, training, and support services for business management systems and software applications.

Related FORsights

Like what you see?
Subscribe to receive tailored insights directly to your inbox.