Reputation: 4003
I am using dependency injection and have come up against something I can't figure out. I have a base class that needs a generic logger:
public class BaseClass
{
public BaseClass(ILogger<BaseClass> logger)
{
// code here
}
}
Then I have a class inheriting that also needs the generic logger:
public class SubClass : BaseClass
{
public SubClass(ILogger<SubClass> logger)
{
// code here
}
}
The problem is that this does not compile with the message; BaseClass does not contain a constructor that takes 0 arguments.
This would be easy to solve if I could do this:
public SubClass(ILogger<SubClass> logger) : base(logger)
The problem is that this is not legal either since ILogger<SubClass>
is not an instance of ILogger<BaseClass>
(it does not compile with The best overloaded match for ... has some invalid arguments).
One possible solution:
I guess I do not have to use constructor injection and instead use the DependencyResolver
.
The question: Surely someone else have come up against this issue before? Is it possible to do with constructor injection? If so, what should I do?
Note: In the current project I am using StructureMap
(for MVC4), but I think that the tool here is slightly irrelevant.
Upvotes: 1
Views: 787
Reputation: 9238
You could add a parameterless constructor in your BaseClass
which would call the parameterized constructor and pass it a manually resolved ILogger
instance. Something like this:
public BaseClass()
: this(ResolveLogger())
{
}
private static ILogger<BaseClass> ResolveLogger()
{
// resolve the instance manually and return it
}
This way, if an instance of type BaseClass
is resolved, it would use the parameterized constructor and inject a resolved ILogger<BaseClass>
instance. But if a derived class is resolved, this derived class would call the parameterless BaseClass()
constructor and the ILogger<BaseClass>
would be resolved manually.
Upvotes: 1
Reputation: 1904
Could you change the logger interface to be :
interface ILogger<out T> where T : BaseClass
Upvotes: 2
Reputation: 817
This happens because ILogger<SubClass>
is not a subclass of ILogger<BaseClass>
so compiler think that you wrote a new constructor. This is implicitly equivalent if you wrote
public class SubClass : BaseClass
{
public SubClass(ILogger<SubClass> logger)
: base() // since base class does not have a constructor
// with no arguments, you will get the error
{
// code here
}
}
So your question is not about dependency injection exactly. It is more about your architecture.
Upvotes: 1