Provider Defined Lookup Tables
Fig supports provider-defined lookup tables through the ILookupProvider
and IKeyedLookupProvider
interfaces. This feature allows applications to dynamically provide lookup table data at runtime, eliminating the need to manually create and maintain lookup tables in the Fig web interface.
Provider-defined lookup tables are the preferred approach for dynamic lookup data. They automatically register when the implementing classes are registered with your application's dependency injection container and are referenced by settings with the [LookupTable]
attribute.
ILookupProvider Interface
The ILookupProvider
interface is used for simple lookup tables where the options are dynamic or only known at runtime.
Implementation
public interface ILookupProvider
{
/// <summary>
/// The name of the lookup table. This must match the name used in the LookupTable attribute on settings.
/// </summary>
string LookupName { get; }
/// <summary>
/// The key of the dictionary is the option value, and the value is an optional alias.
/// </summary>
/// <returns></returns>
Task<Dictionary<string, string?>> GetItems();
}
Example Implementation
using Fig.Client.LookupTable;
public class IssueTypeProvider : ILookupProvider
{
public const string LookupNameKey = "IssueType";
public string LookupName => LookupNameKey;
public Task<Dictionary<string, string?>> GetItems()
{
return Task.FromResult(new Dictionary<string, string?>
{
{ "Bug", "🐛 Bug Report" },
{ "Feature", "✨ Feature Request" },
{ "Task", "📋 Task" },
{ "Documentation", "📚 Documentation" }
});
}
}
Usage in Settings
public class Settings : SettingsBase
{
[Setting("The type of issue being tracked")]
[LookupTable(IssueTypeProvider.LookupNameKey, LookupSource.ProviderDefined)]
public string? IssueType { get; set; }
}
IKeyedLookupProvider Interface
The IKeyedLookupProvider
interface is used for lookup tables where the available options depend on the value of another setting. This creates a cascading dropdown effect.
Interface Definition
public interface IKeyedLookupProvider
{
/// <summary>
/// The name of the lookup table. This must match the name used in the LookupTable attribute on settings.
/// </summary>
string LookupName { get; }
/// <summary>
/// Gets the items for the lookup table.
/// The key of the outer dictionary is the value of the other setting.
/// The key of the inner dictionary is the option value, and the value is an optional alias.
/// </summary>
/// <returns></returns>
Task<Dictionary<string, Dictionary<string, string?>>> GetItems();
}
Keyed Lookup Example
using Fig.Client.LookupTable;
public class IssuePropertyProvider : IKeyedLookupProvider
{
public const string LookupNameKey = "IssueProperty";
public string LookupName => LookupNameKey;
public Task<Dictionary<string, Dictionary<string, string?>>> GetItems()
{
return Task.FromResult(new Dictionary<string, Dictionary<string, string?>>
{
{
"Bug", new Dictionary<string, string?>
{
{ "Critical", "🔴 Critical Priority" },
{ "High", "🟠 High Priority" },
{ "Medium", "🟡 Medium Priority" },
{ "Low", "🟢 Low Priority" }
}
},
{
"Feature", new Dictionary<string, string?>
{
{ "Open", "📭 Open" },
{ "In Progress", "⚡ In Progress" },
{ "Review", "👀 Under Review" },
{ "Closed", "✅ Closed" }
}
},
{
"Task", new Dictionary<string, string?>
{
{ "Alice", "👩💻 Alice (Frontend)" },
{ "Bob", "👨💻 Bob (Backend)" },
{ "Charlie", "🧑💻 Charlie (DevOps)" }
}
}
});
}
}
Usage in Settings with Dependency
public class Settings : SettingsBase
{
[Setting("The type of issue being tracked")]
[LookupTable(IssueTypeProvider.LookupNameKey, LookupSource.ProviderDefined)]
public string? IssueType { get; set; }
[Setting("The specific property for this issue type")]
[LookupTable(IssuePropertyProvider.LookupNameKey, LookupSource.ProviderDefined, nameof(IssueType))]
public string? IssueProperty { get; set; }
}