I have a set of generic classes that are utilized in typed controllers in the following way:
public class RootController<TIndexType, TEntityType> : ControllerBase
{
private readonly IDataFetcher<TEntityType> _dataFetcher;
private readonly IIndexPopulator<TIndexType> _indexPopulator;
private readonly IMapper _mapper;
public RootController(
IIndexPopulator<TIndexType> indexPopulator,
IDataFetcher<TEntityType> dataFetcher,
IMapper mapper)
{
_indexPopulator = indexPopulator;
_dataFetcher = dataFetcher;
_mapper = mapper;
}
}
There are about 15 controllers extending this generic controller with specific types, ie
public class DomainController: RootController<DomainIndex, DomainItem>
Typed versions of IDatFetcher and IIndexPopulator have not been created, as typed instantiation is handled by the DI container.
The issue: I have a hosted BackgroundService that is kicked off at Startup that handles async configuration for the service. As part of this, I need to iterate over all entity types, utilizing IDataFetcher.GetItems to get IEntityType items, map those items to the associated TIndex type, and then pass the mapped TIndex items to IIndexPopulator.PopulateAsync.
I see 3 possible solutions, each with significant drawbacks:
- Create methods to handle data fetching and index population generically based on a list of index types.
- Drawback: I’ve been working through getting this code written and it’s quite complex, plus I’m concerned about performance and maintainability as it requires the extensive use of reflection and/or dynamics.
- Call the associated endpoint in the typed controllers. RootController provides a “/{indexName}/seed” endpoint that covers the needed functionality.
- Drawback: it seems hacky to make an http call to outside the service in order to hit functionality in the service
- Create typed versions of all IDataFetcher and IIndexPopulator classes.
- Drawback: This is a lot of code to write and maintain, any time a new index type is created, the BackgroundService will have to be modified.
Is there another approach I’m missing?