Reputation: 4021
I am in the midst of a Ninject dilema. Moreso, how to bind from multiple areas in my C# solution to the same container. In all, I know that loading via Ninject Modules is the best way to do this, but I won't be able to access the kernel directly (which is as I understand it, an Anti-Pattern anyway) to make calls to _kernel.Get<T>()
.
So it is my belief that constructor injection is the best way to go. Now suppose I have the top level class Program
, which loads the Module : NinjectModule
class
class Program
{
IKernel _kernel;
public static main()
{
_kernel = new StandardKernel();
_kernel.Load(ClassA.Module);
_kernel.Load(ClassB.Module);
}
}
To keep code to a minimum, suppose ClassA modules tied all implementations of ISomething
to ConcreteSomething
, and ClassB
(of which ClassA
is dependant upon) implements the following constructor method;
public ClassB(ISomething thing, int paramA, int paramB)
{
//Do stuff with paramA and paramB using thing
}
In a single solution, the _kernel could be accessed directly, and _kernel.Get<ClassB>.WithConstructorArgument("paramA", 123).WithCon...
However, I am uncertain as to how this would work where the providing class has no access to its callers container.
One thought that crossed my mind would be by using a factory method, but I have no idea how this would work.
Any weight would be appreciated.
Upvotes: 1
Views: 391
Reputation: 13243
You are correct to use constructor injections for dependencies.
How about moving the parameters (paramA, paramB) to a method, like Initialize or Execute?
If that is not reasonable (like when its command), then you will need to use a factory. Have a look at https://github.com/ninject/ninject.extensions.factory.
For use cases not supported by the factory extension, you can always have a factory which gets IResolutionRoot injected. You can do the Get<> on that interface. The factory can reside in any assembly.
public class FactoryB : IFactoryB {
private readonly IResolutionRoot resolutionRoot;
public FactoryB(IResolutionRoot resolutionRoot) {
this.resolutionRoot = resolutionRoot;
}
public IClassB Create(int paramA, int paramB) {
return this.resolutionRoot.Get<IClassB>(new ConstructorArgument("paramA", paramA), new ConstructorArgument("paramB", paramB));
}
}
I wonder however, whether you really need to use a factory for paramA, paramB. This dependends on where the values are coming from / how they are determined. Are they dependent upon classA or are they rather just "global configuration" values?
Upvotes: 1