Tutorial: Extending the C# API

Writing your own helper functions

It is impossible (and undesirable) to add all possible variants of calls to the API. One aim of the API is to be simple enough to get started quickly, but flexible enough to allow reasonably advanced use-cases.

For recurring use-cases, the general methods BridgeFunctionRegistration.WithNaming and BridgeServiceBuilder.FromMethods provides good extension points for custom functionality.

The following are examples of possibly useful extension methods that is better to include as user code than as library-provided extensions, since the variations are endless.

Example: specifying the category

If you e.g. find yourself frequently specifying the category, you could write the following helper method

    public static BridgeFunctionConfiguration WithCategory(
            this BridgeFunctionConfiguration configuration,
            string category)
    {
        return configuration.WithNaming(mi =>
            new NamingOptions { Category = category });
    }

Example: providing descriptions

One way to add descriptions to functions that are exposed to Excel could be to maintain them in a central place and store them in a dictionary. To apply them during function registration an extension method similar to

    public static BridgeFunctionConfiguration WithDescriptions(
        this BridgeFunctionConfiguration configuration,
        IDictionary<string, string> descriptions)
    {
        return configuration.WithNaming(mi =>
            new NamingOptions
            {
                Description = descriptions
                    .TryGetValue(mi.Name, out var description)
                        ? description
                        : null
            });
    }

Adding functions by scanning an assembly for a specific attribute

    public static BridgeServiceBuilder FromAssemblyWithAttribute<T>(
        this BridgeFunctionConfiguration configuration,
        Assembly assembly,
        Func<MemberInfo, T, NamingOptions> namingOptionsBuilder = null)
        where T : Attribute
    {
        var methods = assembly
            .GetTypes()
            .SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.Static))
            .Where(mi => mi.GetCustomAttribute<T>() != null);

        if (namingOptionsBuilder != null)
        {
            configuration = configuration.WithNaming(mi => 
                namingOptionsBuilder(mi, mi.GetCustomAttribute<T>()));
        }

        return configuration.FromMethods(methods);
    }

Read more