Create a .NET Interface Asset

Before proceeding, be sure to review Interface Asset general concepts and our introduction to creating your own interface asset. Treat these articles as prerequisites to the content below.

    Introduction

    IntuiFace Interface Assets support .NET libraries written in C# or VB and rely upon reflection to generate instances, read or write properties and call methods of available objects/classes.

    The following coding requirements are implied:

    1. Classes that will be manipulated by IntuiFace Composer/Player must be public and provide a public argument-less constructor,
    2. These manipulated classes cannot be static class or static instances (singletons). However, you can use static objects within these classes for objects that don't have to be visible within IntuiFace. This is particularly useful when you need a single object (e.g. an object opening a network port) in both Composer's Edit Mode and Play Mode.

    To see an example up close, take a look at this experience posted on our website and the associated C# source code for the custom interface it uses located here.

    Process

    Create the Interface Asset and add it to Composer

    • Create your Dynamic Link Library (DLL) using .NET Framework 4 in a tool like Visual Studio
      • Use a public class as en entry point (see Facade design pattern below)
      • All of its public properties, methods and events are going to be exposed within IntuiFace Composer as Properties, Actions and Triggers
    • Run the GenerateDescriptor tool (see next section for details) on your library then update the generated .ifd file in order to
      • Add titles & descriptions to your properties (the title will be visible in Composer)
      • Add default values (e.g. API key)
    • Add a folder containing your .ifd & .dll(s) into C:\Users\{UserName}\Documents\IntuiFace\Interface Assets

    Update your Interface Asset

    Once an Interface Asset has been added to your experience, there are two ways to update it:

    1. Copy the new files directly into the project folder: {ProjectFolder}\Files\InterfaceAsset\{YourInterfaceAssetFolder}

      OR

    2. Copy the new files into Composer's Interface Assets folder C:\Users\{UserName}\Documents\IntuiFace\Interface Assets AND increment the version number found in the descriptor file. When opening your experience, the files in the project folder will be updated.

    In both cases, to unload the previous dll version, you must close Composer before copying the updated files.

    Assisted Generation of the IntuiFace Descriptor File (.ifd)

    A small command-line tool, named GenerateDescriptor, can be used to generate a complete IntuiFace Descriptor file for a .NET DLL.

    Since it relies upon reflection to identify the properties, events and methods of the descriptor file, the output .ifd will probably contain more than what you want to expose in IntuiFace Composer. (It only checks visibility to determine if a property, event or method will be described in the .ifd.) As a result, you will have to manually delete undesired parts of the .ifd to make it easier to understand and use in Composer.

    Clicke here to download the GenerateDescriptor executable.

    The command line syntax is the following: GenerateDescriptor.exe (DLL Name). You can also drag-and-drop your .dll onto GenerateDescriptor in Windows Explorer (see image below). Either way, the .ifd file is saved in the same folder as the dll, using the same base name as the dll.

    GeneratorDnD.jpg

    Side note considering the usage of third party libraries in C++

    If your C#/VB code wrapping third party C++ libraries, you might get errors when trying to automatically generate the descriptof (.ifd).
    Process:

    • remove the C++ libraries from your build folder
    • follow the process described above to generate the .ifd
    • put the C++ libraries back in the build folder

    The C++ libraries won't be loaded by IntuiFace Player / Composer since they aren't referenced anymore in ths .ifd, but will be loaded by your C#/VB code when using the DLLImport methods.

    Structure of the .ifd Descriptor File

    As mentioned here, a descriptor file (.ifd) is required in order to add an Interface Asset inside an IntuiFace project.

    NOTE: Never edit your .ifd files while Composer is running. If you wish to make changes to a .ifd file, exit out of Composer first.

    A .ifd file for a .NET DLL must obey the following rules :

    All required DLLs must be listed in the "dependencies" propertyThe main DLL must be listed first in the "dependencies" propertyThe "basePath" property denotes the default namespace of the DLL

    Here is an example of an ifd file's global fields as created through use of the GenerateDescriptor tool:

      "id": "EndlessAisle-Selection",
      "name": "EndlessAisle-Selection",
      "version": "1.0",
      "protocol": "dll",
      "baseUrl": null,
      "basePath": "EndlessAisle_Selection",
      "auth": {},
      "dependencies": [
        "EndlessAisle-Selection.dll",
        "PDFNet.dll"
      ],
    

    The description of a C#/VB class must be completed as follows:

    Properties are defined in the "schemas" section of the descriptorMethods and events are defined in the "resources" section of the descriptorBoth schema and resource must share the same "id"

    Remaining part of the example below:

    "schemas": {
         "CartItem": {
             "id": "CartItem",
             "type": "object",
             "properties": {
                "ProductRef": {
                   "$ref": "Product"
                 },
                "Quantity": {
                   "type": "integer"
                 },
                  "TotalPrice": {
                      "type": "number",
                      "format":"double"
                 }       
             }
          }
      },
      "resources": {    
        "CartItem": {
          "isExternalAsset":"true",
          "methods": {
            "IncrementQuantity": {
              "response": {
                "type": "none"
              }
            },
            "DecrementQuantity": {
              "response": {
                "type": "none"
              }
            }
          }
        }
    }
    

    You can download the full .ifd file referenced above here: EndlessAisle-Selection.ifd

    How to reference DLL dependencies

    If your .Net DLL has some dependencies on other DLLs, you have to list all required DLLs in the "dependencies" property.

    In our example, the main DLL EndlessAisle-Selection.dll requires PDFNet.dll

      "id": "EndlessAisle-Selection",
      "name": "EndlessAisle-Selection",
      "version": "1.0",
      "protocol": "dll",
      "baseUrl": null,
      "basePath": "EndlessAisle_Selection",
      "auth": {},
      "dependencies": [
        "EndlessAisle-Selection.dll",
        "PDFNet.dll"
      ],
    

    Best Practices

    Our experience has taught us to respect some important practices when working with .NET DLL Interface Assets.

    Facade Design Pattern

    Your DLL may incorporate a lot of logic, with a mandatory initialization phase, complex object parameters and interactions between many involved classes. Our recommendation is to hide this complex logic behind a Facade, using the dedicated Facade design pattern. Furthermore, this pattern can be used to decompose the underlying complexity (such as Kinect Gesture recognition) to smaller and simpler parts.

    INotifyPropertyChanged Interface implementation

    Each time a method is called on an Interface Asset instance, every property of this instance is reevaluated and visual representations are updated in the IntuiFace experience. This behavior implies significant side effects :

    • If a method modifies the property value of another class instance, this change will not be caught by the associated Interface Asset.
    • If your instance has many properties, a massive refresh can lead to performance issues.

    To solve such potential issues, your class can implement the .NET INotifyPropertyChanged interface. In this case, you will have to implement code to notify the Interface Asset that a property has changed as the properties would no longer be checked by IntuiFace after a method call.

    Sample C# source code:

      private int m_iQuantity = 0;
      public int Quantity
      {
         get { return m_iQuantity; }
         set
         {
            m_iQuantity = value;
            NotifyPropertyChanged("Quantity");
         }
      }
    

    Display a list of items in an Collection

    To feed a Collection like an Asset Grid, Asset Flow, ... with dynamic data, the best and easiest solution is the following:

    • Use an ObservableCollection property in your .NET class to store your dynamic data
    • When you import your .NET Interface Asset in Composer and drag and drop your IA in a scene, an Asset Grid will be automatically created, with its data feed bound to your ObservableCollection
    • Create methods in your .NET IA to add / remove items in your ObservableCollection property. Thanks to the generated binding, your IntuiFace Collection (Asset Grid, Flow, ...) will automatically be updated.

    Don't forget to check the Endless Aisle Retail Sample and download the source code here

    If not done already, you should also check this article to see how to visually represent your dynamic data using a Data Template

    Make your actions asynchronous

    In Player for Windows, actions are called on the graphics thread and thus can block your UI if that action runs a resource-intensive algorithm.

    There are lots of different ways to create an asynchronous method in .NET and it is up to the developer to make a choice. You can find an article about this topic in the Microsoft MSDN documentation.