Project Description
The idea behind this project is provide a way to easily inject configuration information into objects. Ninject does a fine job of injecting objects into other objects, but I didn't find a really nice to get configuration data into my objects.
I tried injecting SettingsBase:
public LogCleaner(SettingsBase settings, IFileSystem fileSystem, IMailClient mailClient)
{
_mailRecipient = settings["MailRecipient"];
_logFolder = settings["LogFolder"];
_fileSystem = fileSystem;
_mailClient = mailClient;
}
Bind<SettingsBase>.ToConstant(Properties.Settings.Default);
but I have to query it with a string and it's difficult to mock. I'm also dependent on the VS generated Settings code, which I'm not particularly fond of. Next I tried passing the arguments directly into the constructor:
public LogCleaner(string mailRecipient, string logFolder, IFileSystem fileSystem, IMailClient mailClient)
{
_mailRecipient = mailRecipient;
_logFolder = logFolder;
_fileSystem = fileSystem;
_mailClient = mailClient;
}
Bind<LogCleaner>().ToMethod(ctx => new LogCleaner(
ConfigurationManager.AppSettings["MailRecipient"],
ConfigurationManager.AppSettings["LogFolder"],
ctx.Kernel.Get<IFileSystem>(),
ctx.Kernel.Get<IMailClient>());
But I still have magic strings and I can't have Ninject automatically inject the constructor - I have to look up the objects and pass them myself. I suppose I could do this:
Bind<LogCleaner>().ToSelf()
.WithConstructorArgument("mailRecipient", ConfigurationManager.AppSettings["MailRecipient"])
.WithConstructorArgument("logFolder", ConfigurationManager.AppSettings["LogFolder"]));
But, come on, be serious... Even MORE magic strings and lots of extra typing. Then I struck on moving the settings into their own object:
public LogCleaner(LogCleanerConfig config, IFileSystem fileSystem, IMailClient mailClient)
{
_config = config;
_fileSystem = fileSystem;
_mailClient = mailClient;
}
public class LogCleanerConfig
{
public LogCleanerConfig(string logFolder, string emailRecipient)
{
LogFolder = logFolder;
EmailRecipient = emailRecipient;
}
public string LogFolder { get; set; }
public string EmailRecipient { get; set; }
}
Better... But now there are TWO bindings and the magic strings have just moved:
Bind<LogCleaner>().ToSelf();
Bind<LogCleanerConfig>().ToMethod(ctx => new LogCleanerConfig(
ConfigurationManager.AppSettings["MailRecipient"],
ConfigurationManager.AppSettings["LogFolder"]);
What I really want to do, is have Ninject grab a configuration item using the parameter's name in the constructor. No more magic strings! So if I wanted to pull my constructor args from AppSettings, I'd do this:
Bind<LogCleaner>().ToSelf();
Bind<LogCleanerConfig>().ToAppSettings();
So! That's what this project let's you do. You can pull configuration data from AppSettings, config sections and the VS-generated Settings object and bind them to objects in Ninject. The constructor parameters are bound conventionally to the configuration
source you specify.