如何用泛型类型注册依赖项注入? (.net核心)

时间:2019-05-23 09:12:43

标签: c# asp.net-core dependency-injection

我有一个asp.net核心网络应用,其中appSettings.json文件中有多个参数。

我不想在构造函数中使用Pandas的服务。

我想要构造函数中的MyObject。 因此,我找到了以下文章:https://weblog.west-wind.com/posts/2017/dec/12/easy-configuration-binding-in-aspnet-core-revisited,这很有趣。

但是我想走得更远。我想创建一个扩展方法来生成注入。

这是我想做的事情:

IOptions<MyObject>

然后在我的ConfigureServices方法中可以调用

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;
        }
    }
}

但是我在这行有一个补充错误:

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

有人知道我该如何纠正错误?

2 个答案:

答案 0 :(得分:1)

如评论中所述,您应将通用约束设置为where T: class,以满足AddSingleton调用的约束。

引用AddSingleton(IServiceCollection, TService)

此外,您可以使用ConfigurationBinder.Get<T>

绑定对象图

引用Configuration in ASP.NET Core : Bind to an object graph

  

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;
    }
}

答案 1 :(得分:0)

您可以使用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