Builder and Configuration
In order for CysTerra to discover your components, you need to define builder types for them. Builder types must be annotated with the ExportAttribute attribute with one of the following contract types.
- IBuilder<ISourceWorker>
- IBuilder<IGenerator<ReportModel>>
- IBuilder<IGenerator<Feature>>
- IBuilder<IGenerator<TTSEntry>>
A discoverable builder type must derive from its contract type, be concrete (not abstract), and have a public parameterless constructor (either explicit or implicit).
For example:
using Cryville.EEW;
using Cryville.EEW.Report;
using System.ComponentModel.Composition;
using System.Globalization;
[Export(typeof(IBuilder<IGenerator<ReportModel>>))]
public class MyReportGeneratorBuilder : IBuilder<MyReportGenerator> {
public override string? GetName([NotNull] ref CultureInfo? culture) {
using var lres = new LocalizedResource("", ref culture);
var res = lres.RootMessageStringSet;
return res.GetStringRequired("SourceName");
}
public MyReportGenerator Build(ref CultureInfo? culture) {
return new MyReportGenerator();
}
}
Builder Configuration
Public browsable settable properties in the builder are recognized as builder configurations configurable by the user. These properties are set by the user before Build is called.
Note that only one component built with the same builder and the same set of builder properties can exist at the same time. If no builder configurations is defined in a builder, only one component built with this builder can exist.
using Cryville.EEW;
using Cryville.EEW.Report;
using System.ComponentModel.Composition;
using System.Globalization;
[Export(typeof(IBuilder<IGenerator<ReportModel>>))]
public class MyReportGeneratorBuilder : IBuilder<MyReportGenerator> {
// Define a configuration named MyConfig
public bool MyConfig { get; set; }
public override string? GetName([NotNull] ref CultureInfo? culture) {
using var lres = new LocalizedResource("", ref culture);
var res = lres.RootMessageStringSet;
return res.GetStringRequired("SourceName");
}
public MyReportGenerator Build(ref CultureInfo? culture) {
// MyConfig has been set by the user here
return new MyReportGenerator(MyConfig);
}
}
Component Configuration
Like builders, components can have component configurations, which is defined in the same way as in builders. However, the component has to implement IPropertiesHolder for its properties to be recognized as configurations.
using Cryville.EEW;
using Cryville.EEW.Report;
using System.Globalization;
// Implement IPropertiesHolder to add configurations
public class MyReportGenerator : IGenerator<MyEvent, ReportModel>, IPropertiesHolder {
// Define a configuration named AdditionalConfig
public bool AdditionalConfig { get; set; }
public ReportModel Generate(MyEvent e, ref CultureInfo culture) {
/* ... */
}
}
Note
Builders actually implement IPropertiesHolder as well because IBuilder derives from it.