dotnet coreはプロファイルで注入されます

23187 ワード

プロファイルの例

{
  //  :"       +     ,       "
  "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
{
    /// 
    ///             。
    /// 
    /// 
    ///                    ,       、         
    /// typeof(AddFromConfigurationFileExtension).Assembly      。
    ///   Type.GetType        。
    /// 
    /// 
    /// 
    /// 
    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);            
    }
}