Skip to content
  • Services
    Our Approach
    Personalized, in-depth technical guidance on a global scale that helps organizations achieve their digital transformation goals.
    Learn more
    • Our Approach
    • Development
    • Design
    • Digital Experience Platform
    • Data & Analytics
    • Cloud & DevOps
    • Support
  • Work
    Our Work
    Through our expertise in strategy, design, and engineering, we help clients deliver digital transformation at scale.
    Learn more
    • Our Work
    • Healthcare
    • Finance
    • Manufacturing
    • Agriculture
    • Education
  • About
    About us
    For over 20 years, we’ve partnered with companies of all sizes and industries to solve their most complex business problems.
    Learn more
    • About us
    • Leadership
    • Locations
    • Events
    • News
  • Careers
    Join our Team
    Take your career to the next level. We offer exciting opportunities across every stage of the software development life cycle.
    Learn more
    • Join our Team
    • Open Positions
    • Application Process
    • Benefits
    • Learning & Development
  • Insights
    Our Insights
    Read our latest blogs, watch our recent videos, and browse our library of e-books — all full of insights from our experts.
    Learn more
    • Our Insights
    • Blog
    • Videos
    • Downloads
  • Contact
Menu
February 22, 2018

Toggle features when delivering your product to multiple clients in .NET Core

There are several ways of doing a feature toggle, choosing the right way depends on what you need to achieve.

Large software products with many complex features often need to be tailored to the different needs of various clients. Getting this right is important, as clients will not want to pay for features that they are not using. Paying for an expensive service only to use 20% of its functionalities is never ideal.

For example, a factory management system that includes access control management, employee management, goods and transportation management, among other things, is designed for manufacturing companies. Ideally, the leaders of a manufacturing company buy only the features they need and plan on using, such as access control and employee management. Perhaps over time, those leaders will decide they need to buy additional functionalities through a service provider.

But the idea of flexible delivery of functions does not pertain only to large and complex applications. You may want to deliver one small feature to some of your clients, but not others. Another option is to deliver experimental or bonus features for clients that have agreed to as much.

For all these cases, it’s necessary to implement some kind of feature toggle.

There are several ways of doing a feature toggle, choosing the right way depends on what you need to achieve. There are pros and cons to consider for each approach.

Approach #1: Using Dynamic Feature Toggle

With this approach, developers produce and ship all of the application’s, but disable and enable specific features based on clients’ predetermined configurations.

What are the Pros and Cons of Approach #1?

Pros

  • Developers can easily enable and disable different features for clients based on their needs without the need of another installation.

Cons

  • When all of the application’s code is delivered to the client, there may be a lot of unused, and therefore unnecessary, code.
  • If teams maintain poor control over client configuration, the client can enable features they are not supposed to access.
How Do You Implement Dynamic Feature Toggle?

For this approach, use a toggle features framework. Here are some of the existing frameworks that do just that:

  • NFeature
  • FlipIt
  • FeatureToggle
  • FeatureSwitcher
  • FeatureBee

Some of this frameworks work only for .NET Framework. The FeatureToggle by Jason Roberts has a version for .NET standards as well. We can also write our own Toggle functionality because the code for that is not big. See this example:

    enum Feature
{
   Feature1,
   Feature2
}

static class FeatureToggle
{
   public static IEnumerable Features { get; set; }
   public static bool IsEnabled(Feature feature) => Features.Contains(feature);
}

public class Startup
{
   public Startup(IConfiguration configuration) =>
       FeatureToggle.Features = configuration.GetValue<string[]>("ActiveFeatures")
                                             .Select(it => Enum.Parse(it));
}

FeatureToggle.IsEnabled(Feature.Feature1);

Approach #2: Deliver Only the Necessary Features


Another option is to deliver to your clients only the features that have been activated, and nothing else. This can be achieved by managing the build process to include or exclude certain modules when building the application.

For example, if a team wants to build the application with only Feature1 and Feature2 included, they can use “& build.ps1 -Feature1 -Feature2” to create the application that includes only those features.

What are the Pros and Cons of Approach #2?

Pros

  • We deliver a smaller package to the client.
  • It is more secure because the client cannot activate any features we don’t want him to use.

Cons

  • It is not flexible because we cannot activate/deactivate features for him. The client needs to reinstall the product to receive new features or we need to provide external auto-update functionality.
How Do You Implement Only the Necessary Features?

First, we need to make sure that every feature is in a different assembly so they can be delivered separately.

Here I have uploaded a project that is an example of this approach. The project represents a calculator that does binary operations. The calculator has two features:

  • BasicCalculator – include addition and subtraction
  • ExtendedCalculator – include division and multiplication.

Here every feature is in a class library so it can be built separately. After we build a feature class library we copy the output files in a staging location.

     
 FeatureToggle.BasicCalculator.csproj and FeatureToggle.ExtendedCalculator.csproj

   <Target Name="AfterBuildCopyFilesToExtLocation" AfterTargets="Build">
      <ItemGroup>
        <_CopyBuildItems Include="$(OutputPath)*.*" />
      </ItemGroup>
       <Copy
          SourceFiles="@(_CopyBuildItems)"
          DestinationFolder="..FeatureToggle.Webobj$(Configuration)ext" />
   </Target> 

And when we build the main application we include the built features that are in the obj/$(Configuration)/ext folder.

Note: ResolvedFileToPublish is a msbuild variable that is used when publishing. See target “ComputeFilesToPublish” in Microsoft.NET.Publish.targets in your current dotnet sdk folder.

  FeatureToggle.Web.csproj

<Target Name="CopyFeatureAssembliesFiles" AfterTargets="CopyFilesToOutputDirectory">
   <ItemGroup>
     <FeatureAssemlies
       Include="obj/$(Configuration)/ext/*.*" />
     <ResolvedFileToPublish Include="@(FeatureAssemlies)">
       <RelativePath>%(Filename)%(Extension)</RelativePath>
     </ResolvedFileToPublish>
   </ItemGroup>
  <Copy
       SourceFiles="@(FeatureAssemlies)"
       DestinationFiles="@(FeatureAssemlies->'$(OutDir)%(Filename)%(Extension)')"
       Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)' != 'true'">
   <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
  </Copy>
 </Target>
How are features excluded from the application?

We are not going to create references to the feature class libraries. We use what is called assembly scanning in LightInject. This feature is included in other DI & IoC frameworks. The idea is that the framework searches for a given assembly and tries to load and register services dynamically from these assemblies.

The basic approach would be to just call:

container.RegisterAssembly("FeatureToggle.*Calculator.dll")

Note: In the example application I have registered my own IAssemblyLoader, because the current default one has some troubles in .NET Core 2.0. Now if we want to only have BasicCalculator feature we do:

dotnet clean
dotnet build FeatureToggle.BasicCalculator
dotnet publish FeatureToggle.Web -o publish

Conclusion

Both approaches are relevant and can be used, depending on how you deliver your applications and what you need.

When you want to dynamically switch features on and off, it is better to use the first approach.
When you want to be more secure, I recommend using the second approach.

Include a feature toggle only when you need to. But at the start of a new software development project, consider whether a feature toggle could be useful, as it becomes more costly the change the application’s design as teams progress through the development lifecycle.

Tags
  • Development
  • Web
  • Support
Share
  • Share on Facebook
  • Share on LinkedIn
  • Share on Twitter
Share
  • Share on Facebook
  • Share on LinkedIn
  • Share on Twitter
Sign up for our monthly newsletter.
Sign up for our monthly newsletter.

Read what's next.

Blog

Increasing the Agility of Agile with Business Analysts

Blog

Five Steps to a Successful Agile Transformation

  • Twitter
  • LinkedIn
  • Instagram
  • Facebook
United States
MentorMate1350 Lagoon Ave, Suite 800
Minneapolis
, MN 55408

+1 612 823 4000
Bulgaria
67 Prof. Tsvetan Lazarov Blvd.
Sofia 1592, Bulgaria,
+359 2 862 2632
Sweden
Drottninggatan 29
411 14 Göteborg

+46 3 199 0180
Paraguay
Carlos M. Gimenez 4855
Asunción, Paraguay

+595 21 327 9463

Copyright © 2023 MentorMate, LLC

  • Cookies
  • Privacy
  • Terms
  • Continuity Policy
This site is registered on wpml.org as a development site.