Simple Injector使用batch registration並呼叫帶參數的Constructor

官方文件中介紹的batch registration的寫法中,沒提到呼叫帶參數的constructor該怎麼寫

只好自己找方法了

原始寫法:

container.Register<IClientRepository>(() => new SqlServerClientRepository(new SqlConnection(connectionString)));

但這樣寫的話,每加一個新的Repo就要手動新增一筆

 

官方文件中有介紹batch registration的寫法,但沒提到呼叫帶參數的constructor的寫法

若參照官方的教學來寫的話會長這樣:

var repositoryAssembly = typeof(SqlServerClientRepository).Assembly;

var registrations =
    from type in repositoryAssembly.GetExportedTypes()
    where type.Namespace == "MyRepo.Repository.SqlServer"
    where type.GetInterfaces().Any()
    select new { Service = type.GetInterfaces().Single(), Implementation = type };

foreach (var reg in registrations)
{
    container.Register(reg.Service, reg.Implementation);
}

我參考stackoverflow上的Using C# reflection to call a constructor,將上面那段程式改為:

var repositoryAssembly = typeof(SqlServerClientRepository).Assembly;

var registrations =
    from type in repositoryAssembly.GetExportedTypes()
    where type.Namespace == "MyRepo.Repository.SqlServer"
    where type.GetInterfaces().Any()
    select new { Service = type.GetInterfaces().Single(), Implementation = type };

foreach (var reg in registrations)
{
    container.Register(
        reg.Service, 
        () => reg.Implementation
                .GetConstructor(new[] { typeof(SqlConnection) })
                .Invoke(new[] { new SqlConnection(connectionString) }));
}

網路上沒找到相關的討論,自己試了一段時間才找出這寫法,留下記錄給後人參考