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);
}