C# DI/IOC. That moment when you cant pass an Inteface through the constructor.
Ok so I managed to pull ConfigurationManager.AppSettings[key]; out into an interface because my test could not access web.config to load a string.
Brilliant (I thought), I was able to mock the IConfiguration like so:
public class PortalConfiguration : IConfiguration { public string GetAppSetting(string key) { return ConfigurationManager.AppSettings[key]; } }
then in my unit test:
_mockConfiguration = new Mock<IConfiguration>();
_mockConfiguration .Setup(m => m.GetAppSetting(It.IsAny<string>())) .Returns("http://localhost:8090");
which worked because previously, the method I was testing had a hard coded
ConfigurationManager.AppSettings[key];
in it - which was null - so the test failed.
Now I had a passing test and felt good.
Then I tried to run my application and it crashed because I had to inject a concrete IConfiguration (using StructureMap) into a class at runtime.
This is what caused the problem:
public Startup(IConfiguration configuration) { _configuration = configuration; }
I could not modify the caller of this class becuase it lived beyond my code somewhere in the .NET framework.
So I did this instead:
public Startup() { // cannot pass IConfiguration through ctor because // the core/metadata expects an empty constructor _configuration = IocConfig.Setup().GetInstance<IConfiguration>(); }
Which essentially does the same thing - it asks my DI Container for which concrete implementation to use (just as it would do if I could have used the code that caused the problem.
If you know another way in which I could have accomplished this, do share.






