Как зарегистрировать внедрение зависимостей с универсальными типами?(ядро .net) - PullRequest
0 голосов
/ 23 мая 2019

У меня есть основное веб-приложение asp.net с несколькими параметрами в файле appSettings.json.

Я не хотел, чтобы в конструкторе были службы с IOptions<MyObject>.

Я хотелMyObject в конструкторе.Поэтому я нашел следующую статью: https://weblog.west -wind.com / posts / 2017 / dec / 12 / easy-configuration-binding-in-aspnet-core-revisited , что очень интересно.

Но я хочу пойти дальше.Я хотел бы создать метод расширения для генерации инъекции.

Вот что я хотел бы сделать:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Common.WebTools.Extensions
{
    public static class IServiceCollectionExtensions
    {
        public static IServiceCollection AddSingletonConfigurationObject<T>(this IServiceCollection services, 
            IConfiguration configuration,
            string appSettingsKey) where T:new()
        {   
            var obj2 = new T();
            configuration.Bind(appSettingsKey, obj);
            services.AddSingleton(obj2); //compilation failed
            return services;
        }
    }
}

А затем в моем методе ConfigureServices я могу вызвать

services.AddSingletonConfigurationObject<Common.Tools.Configuration.GoogleAnalyticsConfiguration>(Configuration, "GoogleAnalytics");

Но у меня есть ошибка компиляции в этой строке:

services.AddSingleton(obj2); 

Кто-нибудь знает, как я могу исправить ошибку?

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Как указано в комментариях, вы должны установить общее ограничение на where T: class, чтобы удовлетворить ограничение вызова AddSingleton.

Ссылка AddSingleton (IServiceCollection, TService)

Кроме того, вы можете связать граф объектов, используя ConfigurationBinder.Get<T>

Ссылка Конфигурация в ASP.NET Core: Связать с графом объектов

ConfigurationBinder.Get<T> связывает и возвращает указанный тип.Get<T> удобнее, чем Bind.

как в следующем примере

public static class IServiceCollectionExtensions {
    public static IServiceCollection AddSingletonConfigurationObject<TService>(
        this IServiceCollection services, 
        IConfiguration configuration,
        string appSettingsKey) where TService: class
    {   

        var setting = configuration.GetSection(appSettingsKey).Get<TService>();
        services.AddSingleton(setting);
        return services;
    }
}
0 голосов
/ 23 мая 2019

Вы можете использовать services.AddScoped для использования только 1 экземпляра в запросе области. Так что в целом улучшение по сравнению с AddTransient

services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));

Так что мой интерфейс и класс будут выглядеть так

public interface IGenericRepository<T> where T : class
public class GenericRepository<T> : IGenericRepository<T> where T : class
...