プロファイルの例
{
"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
{
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);
}
}