dotnet core通过配置文件进行注入

配置文件示例

{
  //描述:"实现类命名空间+实现类名称,所在程序集名称"
  "Services": {
    "Singleton": [

    ],
    "Transient": [
      {
        "Service": "Cy.NetCore.Common.Interfaces.IService,Cy.NetCore.Common.Interfaces",
        "Implementation": "Cy.NetCore.Common.DataBase.ServiceImpl.ServiceA,Cy.NetCore.Common.DataBase"
      }
    ],
    "AddScoped": [

    ]
  }
}

配置文件反序列化类

public class ServicesConfiguration
{
    public IEnumerable<ServiceItem> Singleton { get; set; }
    public IEnumerable<ServiceItem> Transient { get; set; }
    public IEnumerable<ServiceItem> AddScoped { get; set; }
}
public class ServiceItem
{
    public string Service { get; set; }
    public string Implementation { get; set; }
}

注入实现的扩展方法

public static class AddFromConfigurationFileExtension
{
    /// <summary>
    /// 通过配置文件进行注入实现。
    /// </summary>
    /// <remarks>
    /// 需要注意的是由于通过的配置文件进行配置,那么要确保接口、实现对应的程序集和
    /// typeof(AddFromConfigurationFileExtension).Assembly程序集同目录。
    /// 不然Type.GetType会找不到对应的类。
    /// </remarks>
    /// <param name="services"></param>
    /// <param name="configuration"></param>
    /// <returns></returns>
    public static IServiceCollection AddFromConfigurationFile(this IServiceCollection services,
    IConfigurationSection configuration)
    {
        var servicesConfiguration = configuration.Get<ServicesConfiguration>();            
        Type @interface = null, implementation = null;
        if (servicesConfiguration.Singleton != null)
        {
            foreach (var service in servicesConfiguration.Singleton)
            {
                @interface = Type.GetType(service.Service, false);
                implementation = Type.GetType(service.Implementation, false);
                if (@interface == null)
                    throw new ArgumentNullException($"{service.Service}未找到。请和管理员联系!", nameof(@interface));
                if (@interface == null)
                    throw new ArgumentNullException($"{service.Implementation}未找到。请和管理员联系!", nameof(implementation));
                services.AddSingleton(@interface,implementation);
            }
        }
        if (servicesConfiguration.Transient != null)
        {
            foreach (var service in servicesConfiguration.Transient)
            {
                //确保能够正确注册。防止影响后面的功能。
                @interface = Type.GetType(service.Service, false);
                implementation = Type.GetType(service.Implementation, false);
                if (@interface == null)
                    throw new ArgumentNullException($"{service.Service}未找到。请和管理员联系!", nameof(@interface));
                if (@interface == null)
                    throw new ArgumentNullException($"{service.Implementation}未找到。请和管理员联系!", nameof(implementation));
                services.AddTransient(@interface, implementation);
            }
        }
        if (servicesConfiguration.AddScoped!=null)
        {
            foreach (var service in servicesConfiguration.AddScoped)
            {
                //确保能够正确注册。防止影响后面的功能。
                @interface = Type.GetType(service.Service, false);
                implementation = Type.GetType(service.Implementation, false);
                if (@interface == null)
                    throw new ArgumentNullException($"{service.Service}未找到。请和管理员联系!", nameof(@interface));
                if (@interface == null)
                    throw new ArgumentNullException($"{service.Implementation}未找到。请和管理员联系!", nameof(implementation));
                services.AddScoped(@interface, implementation);
            }
        }
        return services;
    }
}

使用NUnit进行单元测试

[TestFixture]
internal class Tests
{
    private ServiceProvider serviceProvider;
    private IService _service;

    [SetUp]
    public void Setup()
    {
        var build = new ConfigurationBuilder()
           .SetBasePath(Directory.GetCurrentDirectory())
           .AddJsonFile("configuration.json", optional: true, reloadOnChange: true);
        var config = build.Build();
        ServiceCollection services = new ServiceCollection();
        services.AddFromConfigurationFile(config.GetSection("Services"));
        serviceProvider=services.BuildServiceProvider();
        _service = serviceProvider.GetRequiredService<IService>();
    }

    [Test]
    public void TestService()
    {
        int a = 10, b = 10;
        var result = _service.Calculation(a, b);
        Assert.NotNull(result);
        Assert.AreEqual(result, 20);            
    }
}
posted @ 2019-05-30 16:42  Jonny-Xhl  阅读(249)  评论(0编辑  收藏  举报