C
C#2y ago
Hugh

✅ When using Dependency Injection, how can I pass other parameters into the constructor?

I'm just starting to get my head around the basics of DI. I've got a number of instances that were being manually created, and I'm working to get them shifted over to using DI. Having references to other classes in the constructor makes some kind of sense to me now. However, I'm now wondering if there's a way to pass other values into the constructor. For example, if I have the following, how could I define what version is in the constructor, and is that even possible? If it's not possible, then if it's a nullable type
public class MyService : IHostedService
{
private readonly SemVersion _version;
private readonly ILogger _logger;

public MyService(ILogger<MyService> logger, SemVersion version)
{
_logger = logger;
_version = version;
}

public async static Task Main()
{
SemVersion serviceVersion = new SemVersion(0, 1, 0);

IHostBuilder builder = Host.CreateDefaultBuilder();
builder.ConfigureServices(services =>
{
services.AddHostedService<MyService>();
});

IHost host = builder.Build();
await host.StartAsync();
}

// Other stuff, including StartAsync() and StopAsync()
}
public class MyService : IHostedService
{
private readonly SemVersion _version;
private readonly ILogger _logger;

public MyService(ILogger<MyService> logger, SemVersion version)
{
_logger = logger;
_version = version;
}

public async static Task Main()
{
SemVersion serviceVersion = new SemVersion(0, 1, 0);

IHostBuilder builder = Host.CreateDefaultBuilder();
builder.ConfigureServices(services =>
{
services.AddHostedService<MyService>();
});

IHost host = builder.Build();
await host.StartAsync();
}

// Other stuff, including StartAsync() and StopAsync()
}
Having played a bit more while writing this question, this seems to work, but it only allows one value per type, and it doesn't feel like it's the right way to do it...
services.Add(new ServiceDescriptor(typeof(SemVersion), serviceVersion));
services.Add(new ServiceDescriptor(typeof(SemVersion), serviceVersion));
What's the best approach to this kind of thing? Thanks
9 Replies
Hugh
Hugh2y ago
I've just found this SO post which I think answers my question... https://stackoverflow.com/questions/34834295/dependency-injection-inject-with-parameters
Stack Overflow
Dependency injection, inject with parameters
I'm using vNext implementation of DI. How to pass parameters to constructor? For example, i have class: public class RedisCacheProvider : ICacheProvider { private readonly string _connectionS...
Hugh
Hugh2y ago
I'll leave this open for a bit in case anyone else has any comments on this approach I've now got:
builder.ConfigureServices(services =>
{
services.AddHostedService<MyService>(provider => new MyService(provider.GetService<ILogger<MyService>>()!, serviceVersion);
});
builder.ConfigureServices(services =>
{
services.AddHostedService<MyService>(provider => new MyService(provider.GetService<ILogger<MyService>>()!, serviceVersion);
});
What I don't like about this is that GetService() returns a T?, and so I need to either manually check, accept an ILogger? in MyService or add a ! at the end, none of which feel great
Anton
Anton2y ago
you have to use a factory or a provider GetRequiredService returns a T
Hugh
Hugh2y ago
ahh - awesome thanks - didn't spot that one I think I'll go with this then. Thanks! It's a bit of a shame that I can't just add new things to the MyService contstructor and have them appear - I have to add them in 2 places, but that's fine
Anton
Anton2y ago
if it's gonna be just a single instance of the version, you can register that with DI also
Hugh
Hugh2y ago
Would that be using:
services.Add(new ServiceDescriptor(typeof(SemVersion), serviceVersion));
services.Add(new ServiceDescriptor(typeof(SemVersion), serviceVersion));
Because it would need to be a specific instance or, I guess, I could use AddSingleton with a provider...
services.AddSingleton<SemVersion>(provider => serviceVersion);
services.AddSingleton<SemVersion>(provider => serviceVersion);
Anton
Anton2y ago
just AddSingleton(version) should work
Hugh
Hugh2y ago
ah - very cool I think that'll be my approach then As it will just be the one instance of that type appreciate it! (always helpful)
Anton
Anton2y ago
np
Want results from more Discord servers?
Add your server
More Posts