I’m using the Unity IoC container for the first time, and overall I like it. But one under-documented and slightly unintuitive area caused me some trouble.
Suppose I have a ThreadPool class:
class ThreadPool { public ThreadPool(int maxThreads) { ... } }
I can register this in the container as follows:
container.RegisterType<ThreadPool>(new InjectionConstructor(20));
So every time the container creates an instance of ThreadPool, it will pass 20 for the maxThreads argument. It’s not the most intuitive API, but it does the job.
However suppose I now extend my ThreadPool class to add logging, i.e.:
class ThreadPool { public ThreadPool(int maxThreads, ILogger logger) { ... } }
How do I modify my container registration to inject the correct ILogger instance? Of course I could just create a Logger instance and pass it as an extra argument to InjectorConstructor, but that’s not the behaviour I want. I want the container to resolve ILogger when the ThreadPool instance is being resolved. Having looked through the documentation, I was coming to the conclusion that this wasn’t possible, but then I came across this post on pnpguidance.net that shows how it’s done:
container.RegisterType<ThreadPool>(new InjectionConstructor(20,typeof(ILogger)));
I suppose using typeof in this scenario makes some sense, but it’s hardly intuitive. The API could be improved so that I don’t need to specify anything about ILogger resolution at all. I should only have to specify explicitly the constructor arguments that cannot be resolved automatically, e.g.:
container.RegisterType<ThreadPool>().WithConstructorArg("maxThreads", 20);