web-dev-qa-db-fra.com

Impossible de résoudre le service pour le type IOptions [DataAccessConfiguration] dans une application autre que ASP.NET Core

Tous nos services professionnels étaient précédemment configurés pour utiliser l'injection de dépendances avec IOptions, car ils étaient utilisés par les applications ASP.NET Core, comme suit:

NotificationDataAccess.cs:

public class NotificationDataAccess : BaseDataAccess, INotificationDac<Notification>
    {
        public NotificationDataAccess(IOptions<DataAccessConfiguration> options, IClaimsAccessor claimsAccessor) :
            base(options, claimsAccessor)
        {
        }
}

NotificationBusinessService.cs:

public class NotificationBusinessServices : INotificationServices<Notification>
    {
        private readonly INotificationDac<Notification> _notificationDataAccess;

        public NotificationBusinessServices(
            INotificationDac<Notification> notifcationDataAccess)
        {
            _notificationDataAccess = notifcationDataAccess;
        }
}

Il me reste maintenant la tâche peu enviable d’essayer de comprendre comment tirer parti du même schéma d’un service Windows, qui ne bénéficie pas des fonctionnalités intégrées ASP.NET Core pour la gestion de DI. Lorsque le service démarre, j'exécute le code suivant:

// Set up configuration, services, and logging.
            IServiceCollection services = new ServiceCollection();
            var startup = new Startup();
            startup.ConfigureServices(services);
            IServiceProvider serviceProvider = services.BuildServiceProvider();

            var configuration = serviceProvider.GetService<IConfigurationRoot>();
            var notificationService = serviceProvider.GetService<INotificationServices<Notification>>();// TODO: This errors!
            processor = new Processor(configuration, notificationService);

Et voici le code Startup.cs, qui est censé configurer les services:

public class Startup
    {
        IConfigurationRoot Configuration { get; }

        public Startup()
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Path.Combine(AppContext.BaseDirectory))
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IConfigurationRoot>(Configuration);
            //services.AddMvc();

            // Add application services.
            Listings.Business.Configuration.Instance = new BusinessLayerConfiguration();
            services.Configure<DataAccessConfiguration>(options => Configuration.GetSection("Data").Bind(options));
            services.AddScoped(typeof(INotificationDac<Notification>), typeof(NotificationDataAccess));
            services.AddScoped(typeof(INotificationServices<Notification>), typeof(NotificationBusinessServices));
        }
    }

Malheureusement, lorsque j'exécute le service Windows, une exception est générée lors de la tentative d'obtention de notificationService:

var notificationService = serviceProvider.GetService<INotificationServices<Notification>>();

L'exception est:

System.InvalidOperationException: 'Impossible de résoudre le service pour le type ' Microsoft.Extensions.Options.IOptions`1 [Rpr.Listings.DataAccess.DataAccessConfiguration] ' Lors d'une tentative d'activation de 'Rpr.Listings.DataAccess.NotificationDataAccess'. '

J'espérais que mon code "services.Configurer" résoudrait ce problème, mais hélas non. Il est clair que je dois enregistrer IOptions dans mon Startup.cs, mais je ne sais pas comment le faire. Est-ce quelque chose qui arrive habituellement avec ASP.NET MVC? Est-ce que "services.AddMvc ();" normalement enregistrer cette liaison correctement? Je peux appeler cela, mais je devrais importer une tonne de packages ASP.NET MVC dans mon service Windows, ce que je suis réticent à faire.

S'il vous plaît laissez-moi savoir comment enregistrer la liaison IOptions correctement, merci!

7
Justin

Il se trouve que tout ce qui me manquait était:

services.AddOptions();

Une fois que j'ai ajouté cela, la liaison d'IOptions a été enregistrée correctement!

19
Justin

Au cas où cela aiderait quelqu'un, le problème était lié à une application de console et avait été causé par la création du fournisseur de services. 

IServiceProvider serviceProvider = services.BuildServiceProvider();

avant d'avoir enregistré ma config

services.Configure<DataAccessConfiguration>(Configuration.GetSection("Data"));
1
greentrees