How to Make Extensions

The release of Mendix Studio Pro 10.12 was also the introduction of extensions. If you aren’t sure what this means, extensions are a way to edit the Studio Pro IDE itself and create customized work environments bespoke to your development team.

 

This blog will focus on the practical aspects of developing an extension. I’ll show you how to set up your development environment, which includes how to install Visual Studio and how to get access to the Mendix Extensions API via NuGet. Finally, I’ll cover how to make your first simple extension for the top-level menu and how to make your own dockable pane.

 

Installing Visual Studio 2022

Extensions are built using C# (currently), so we recommend using Visual Studio 2022 for this exercise. You can, of course, use other IDEs of your choice. But I will be using Visual Studio 2022 for the C# side of this build.

 

If you’ve never used Visual Studio before, don’t worry. Once you’ve downloaded it for free it’s quite easy to set up. You can find it on Microsoft’s official download site here.

 

Once you’re ready to install, it’s important to properly configure the installer to enable:

  • .Net Desktop development
  • .Net Multiplatform app

UI development

Once Visual Studio finishes installing, we can finally get started on creating a new project.

In Visual Studio choose “New Project”. Then search for “C# class library” and click next.

Next, you will have to enter a name. (Any name is fine.)

 

Finally, select a .Net version. You need to choose .Net 8.0. Once you’re done, confirm your choices and open the project.

Getting the NuGet package

Mendix has tools for developing extensions, but we need the NuGet package manager to get them.

 

In Visual Studio you will find NuGet under the Project top level menu. If it’s not there, don’t worry. Just click “Get tools and features,” and search for NuGet. You may need to download some installation files. Once you have it installed, click on the option to “manage Nuget packages” found under Project.

 

Switch to the “Browse” tab. Then simply search for Mendix. You should get this result: Mendix.StudioPro.ExtensionsAPI. This package is the Extensions API made available to download.

If you would like to read the API Docs for this and see everything the API has to offer, you can find it on Github. You can also find some examples to go with it if you want to download some code samples while you’re at it.

 

Make sure Extensions API is installed. You will know it’s installed after you accept the license agreement because the “Install” button will now say “uninstall.”

 

Enabling the Extensions Feature Flag for Studio Pro

Visual Studio is all set up now. You just need to make sure you can test your extension in Studio Pro. To do this you need to enable the feature flag. This is quite simple. All you need is to a shortcut to your Mendix version. (Mine is 10.12.1.)

 

Right click on the shortcut on your desktop. In this field we need to go right to the end and add “–enable-extensions-development”. This is going to tell Studio Pro that we are developing some extensions. It will turn on this feature for us to use.

Creating a Menu Extension

The first step to creating any extension is to create a manifest file. To do this, right-click on the project in the “Solution Explorer.” Click on “Add” and then on “New Item.” Name the file “manifest.json”, all lowercase

 

Before you add any code here, you need to change the option in the properties window from “Copy to Output Directory” to “Copy Always.” This is important because the manifest.json file is what tells Studio Pro there is an extension and which files are available.

After this you can add a simple JSON statement to define the extension as follows:

 

{
  "mx_extensions": [ "YourExtensionName.dll" ],
  "mx_build_extensions": []
}

 

Once we are done creating the manifest file, we can move on to creating the menu item.

 

Right-click on your project and add a new item once again. Give your new file a name, something like “MyMenuExtension.cs”, and click Add.

 

Visual Studio will prepopulate the file with some skeleton code. You should see the following:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyFirstExtension
{    internal class MyMenuExtension
    {
    }
}

 

We need to make sure that the class is exported as a Menu Extension. We can do this with some basic scaffolding:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyFirstExtension
  [method:ImportingConstructor]    //Define the method  
  [Export(typeof(MenuExtension))]  //Export the class as type Menu Extension

  {    internal class MyMenuExtension
      {
      }
  }

 

Next, we need to define the return type and call a message box service using the Extensibility API:

 

using Mendix.StudioPro.ExtensionsAPI.UI.Menu;
using Mendix.StudioPro.ExtensionsAPI.UI.Services;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace MyFirstExtension
{
    [method:ImportingConstructor]
    [Export(typeof(MenuExtension))]
    public class MyMenuExtension(IMessageBoxService messageBoxService):MenuExtension //change from internal to public class and define this as a Menu Extension
    {
        public override IEnumerable GetMenus()//GetMenu allows you to return new Menu Items (Extensibility API)
        {
            yield return new MenuViewModel("Say Hello", () => messageBoxService.ShowInformation("Hello World!"));// MenuViewModel accepts 2 parameters, the first is the Menu Label which is the caption which will be displayed in studio pro. The second is the desired action which in this case is a inline function which calls a message box function

 

After adding this code, you will have successfully created your first extension! You then only need to compile this into a usable “.dll” file. To compile it, go to the “Build” menu item and click on build “your project name” or press Shift + f6 on your keyboard.

 

Importing the New Extension into Your Mendix Project

The final step is to add the new extension to your project in Studio Pro. This is quite simple. It simply requires youto copy the compiled code from its build output folder to your Mendix app directory.

 

To view the compiled files, right click on your project in Visual Studio and click on “open folder in file explorer.” Once there your files will be in “MyFirstExtension\MyFirstExtension\bin\Debug\net8.0”

 

You will see four files here. We need to copy them into your Mendix app directory.

In your Mendix app directory, create a new folder called “extensions”. In this folder create a new subfolder called “myExtensionsName”. Paste the four files from your compiled C# project into this new folder.

 

After copying the extension into your Mendix App directory, return to Studio Pro and Click “Synchronise App Directory” or simply hit f4. If you have been successful with your build, you will immediately see a new “Extensions” menu item inside Studio Pro. If you click into it, you will see your menu extension. Clicking it should trigger a message box that says, “hello world.”

Creating a Dockable Pane Extension

The final piece is to add a Dockable pane. Dockable panes are the windows in Studio Pro that provide various information about the app. However, you can create a dockable pane to do anything.

 

In this case, I will create a dockable pane that uses a webview to load in a website or URL. To save time, I will add this into the existing extension, but you can do this as a standalone extension if you wish.

 

To start we need to add a new “yield return” statement to handle the new docking window.

 

using Mendix.StudioPro.ExtensionsAPI.UI.Menu;
using Mendix.StudioPro.ExtensionsAPI.UI.Services;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace MyFirstExtension
{
    [method:ImportingConstructor]
    [Export(typeof(MenuExtension))]
    public class MyMenuExtension(IMessageBoxService messageBoxService):MenuExtension //change from internal to public class and define this as a Menu Extension
    {
        public override IEnumerable GetMenus()//GetMenu allows you to return new Menu Items (Extensibility API)
        {
          
            yield return new MenuViewModel("Say Hello", () => messageBoxService.ShowInformation("Hello World!"));
            yield return new MenuViewModel("Open Pane", () => dockingWindowService.OpenPane(MyDockablePaneExtension.ID));// new yield to return the new pane

        }
    }
}

 

For this code to work, we need to create a new MyDockablePaneExtension that is returned. To do so right-click on the project once again in the solution explorer, choose “Add Item,” and add a new class called “MyDockablePaneExtension”. Open the file the same was as you did as the first extension.

using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyFirstExtension
{
    [Export(typeof(DockablePaneExtension))]//Export the file as a dockable pane

    public class MyDockablePaneExtension : DockablePaneExtension
    {
        public const string ID = "my-dockable-pane";//define and ID
        public override string Id => ID; //override ID with id
        public override DockablePaneViewModelBase Open() => new MyDockablePaneExtensionWebViewModel("https://www.youtube.com/@MendixCommunity");//Open a URL using a WebViewModel
    }
}
/code>

You will likely have an error now, as the class called in the final line “MyDockablePaneExtensionWebViewModel” does not exist yet.

 

Create a new file as before. Give it the name “MyDockablePaneExtensionWebViewModel.cs”. “The new class will require the URL as a parameter, and will display it using the Extensions API method WebViewDockablePaneViewModel().

using Mendix.StudioPro.ExtensionsAPI.UI.DockablePane;
using Mendix.StudioPro.ExtensionsAPI.UI.WebView;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyFirstExtension
{
    internal class MyDockablePaneExtensionWebViewModel(string myURL) : WebViewDockablePaneViewModel//String myURL parameter passed in (your desired URL) + WebViewDockablePaneViewModel ->extensions API
    {
        public override void InitWebView(IWebView webView) => webView.Address = new Uri(myURL);//opens the url in the Webview
    }
}

With this the dockable pane is complete. You can repeat the build process in Visual Studio and then copy the updated build output into your extensions folder in your Mendix App Directory. Make sure to replace the old files with the new ones and to synchronize your app directory in Mendix again.

 

Your dockable pane should now appear in your new menu items under the Extensions menu.

Conclusion

The ability to directly modify Studio Pro is an absolute game changer. And the ability to display a website with minimal coding means you can repurpose existing websites—for example, a Mendix app—as a new extension with a few simple class definitions in C#.

 

I look forward to seeing what the addition of extensions will bring, and I can’t wait to see what amazing creations our community creates.

 

For a full breakdown of how everything works, head over to the Mendix Docs pages to read more about Extensibility, or go to the API docs on Github.com and explore what is possible.