ASP.Net Core 2 Unable to resolve service for type
Asked Answered
M

1

6

I'm attempting to register my own custom options. I have, in my ASP.Net project (Kimble.API), an appsettings.json file. It looks like this:

{
    "NotificationHub": {
        "AccountName": "my-notification-hub-name",
        "ConnectionString": "my-secret-connection-string"
    }
}

In my .Net Standard library (Kimble.Core), which the API project references, I have a class NotificationHubOptions:

public class NotificationHubOptions
{
    public string AccountName { get; set; }
    public string ConnectionString { get; set; }
}

Back to the API project.

In my Startup.cs file, in the ConfigureServices method, I register the options:

services.Configure<NotificationHubOptions>(configuration.GetSection("NotificationHub"));

I've checked, and the registration does show up in the services collection.

My controller's constructor looks like this:

public MyController(NotificationHubOptions options)
{
    _notificationHubOptions = options;
}

However, when I try to call a method on the controller, I always get an exception:

System.InvalidOperationException: 'Unable to resolve service for type 'Kimble.Core.Options.NotificationHubOptions' while attempting to activate 'Kimble.API.Controllers.MyController'.'

This all worked before I moved the NotificationHubOptions class to my Core project. However, I can't see why that should matter at all.

Millisecond answered 31/1, 2018 at 19:4 Comment(0)
C
15

You need to inject IOptions<TOptions>, like so:

public MyController(IOptions<NotificationHubOptions> options)
{
    _notificationHubOptions = options.Value;
}

When you use Configure, you are registering a callback to configure the options instance for that type when it creates it. In this case using the configuration section to bind data to the options object.

So the options class itself is not in DI.

If you wanted that you could do this:

var options = Configuration.GetSection("NotificationHub").Get<NotificationHubOptions>();
services.AddSingleton<NotificationHubOptions>(options);
Caesarea answered 31/1, 2018 at 19:20 Comment(2)
Ah... Now I remember; I used to actually be doing it the first way you mentioned. I'm completely rewriting my backend, and apparently somewhere in there I lost that IOptions<> bit. But I tried your second suggestion since I like the look of it better, and it worked wonderfully. Thanks!Millisecond
Or: services.AddSingleton(s => s.GetService<IOptions<NotificationHubOptions>>().Value);Ephemerality

© 2022 - 2024 — McMap. All rights reserved.