I have code that fetches different templates for HTML and CSS in the file system. The templates are stored in different folders, so I have two implementations for the code that fetches them, passing the correct path as a parameter.
private string _templatePath;
private readonly IConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
public BaseTemplateFileService(string templatePath,
IConfigurationManager configurationManager,
IFileSystem fileSystem)
{
_templatePath = templatePath;
_configurationManager = configurationManager;
_fileSystem = fileSystem;
}
protected abstract string GetExtensionPattern(string templateName);
public string GetTemplate(string templateName)
{
var templatesPath = _configurationManager.GetAppSetting(_templatePath);
var fullName = GetExtensionPattern(templateName);
var templatesFolder = _fileSystem.DirectoryInfo.FromDirectoryName(templatesPath);
var files = templatesFolder.GetFiles(fullName, SearchOption.AllDirectories);
var totalNumberOfFiles = files.Count();
if (totalNumberOfFiles < 1)
{
throw new PanelException(string.Format("No template file to choose with name: {0}", fullName));
}
if (totalNumberOfFiles > 1)
{
throw new PanelException(string.Format("Multiple template files to choose with name: {0}", fullName));
}
using (var streamReader = files[0].OpenText())
{
var content = streamReader.ReadToEnd();
return content;
}
}
public class HtmlTemplateFileService : BaseTemplateFileService
{
public HtmlTemplateFileService(IConfigurationManager configurationManager,
IFileSystem fileSystem)
: base("panelHtmlPath", configurationManager, fileSystem)
{
}
protected override string GetExtensionPattern(string folderName)
{
return string.Format("{0}.htm*", folderName);
}
}
public class CssTemplateFileService : BaseTemplateFileService
{
public CssTemplateFileService(IConfigurationManager configurationManager,
IFileSystem fileSystem)
: base("panelCssPath", configurationManager, fileSystem)
{
}
protected override string GetExtensionPattern(string folderName)
{
return string.Format("{0}.scss*", folderName);
}
}
What I don't like about this approach is that I need to set up my IoC contaier (i.e. Unity) like this
container.RegisterType<CssPanelGenerator>(new InjectionConstructor(
new ResolvedParameter<ITemplateService>("cssTemplateService"), typeof(CssVariableService), typeof(ProcessSass)));
and same for the HTML one.
Is there a cleaner way to avoid code repetition but without the need to use this slightly more convoluted way of doing dependency injection that I can't think of?