I'm using ASP.NET Core Web API. I am having a hard time wrapping my head around instantiating a non-controller class that uses DI. There are a multitude of SO articles related to this, but none that have answered my question (as far as I can understand). These are the most popular and relevant:
Net Core Dependency Injection for Non-Controller
Dependency Injection without a Controller
ASP.NET 5 Non-Controller DI injection
My use case (a contrived example):
I have a class SpeechWriter
that has a dependency on IRandomTextService
:
public class SpeechWriter
{
private readonly IRandomTextService _textService;
// Constructor with Text Service DI
public SpeechWriter(IRandomTextService textService)
{
_textService = textService;
}
public string WriteSpeech()
{
var speech = _textService.GetText(new Random().Next(5,50));
return speech;
}
}
IRandomTextService
interface:
public interface IRandomTextService
{
public string GetText(int wordCount);
}
and the implementation:
public class RandomTextService : IRandomTextService
{
public string GetText(int wordCount)
{
return Lorem.Words(wordCount);
}
}
IRandomTextService
is registered as a service in Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IRandomTextService, RandomTextService>();
}
In my controller action, if I want to instantiate a SpeechWriter
like this:
public IActionResult Index()
{
var speech = new SpeechWriter();
return Ok(speech.WriteSpeech());
}
I can't do it because an argument (the injected service) is expected.
The only way I can seem to get DI to inject RandomTextService
in SpeechWriter
is if SpeechWriter
itself is a service and injected in the controller:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IRandomTextService, RandomTextService>();
services.AddScoped<SpeechWriter>();
}
public class EchoController : ControllerBase
{
private readonly SpeechWriter _speechWriter;
public EchoController(SpeechWriter speechWriter)
{
_speechWriter = speechWriter;
}
public IActionResult Index()
{
return Ok(_speechWriter.WriteSpeech());
}
}
Is there any way to get RandomTextService
injected when SpeechWriter
is instantiated as in my first example, like this?
var speech = new SpeechWriter();
If not, what is it about DI that I'm missing? My actual application is more complex than this and I would effectively have to create a chain of DI and services all the way back up to the controller. I could use the ServiceProvider
"anti-pattern", but I prefer not to do that because I'd be passing ServiceProvider
all over the place.
Please help educate me!
Thanks.