Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piyoEsq/d78ec10c56d7f7c925096567a90079be to your computer and use it in GitHub Desktop.
Save piyoEsq/d78ec10c56d7f7c925096567a90079be to your computer and use it in GitHub Desktop.
Auto register services to DI Container of GenericHost that use Microsoft.Extensions.DependencyInjection.
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Sample.GenericHost
{
// Command
public interface ICommand { }
public interface ICommandHandler<TRequest> where TRequest : ICommand
{
void Handle(TRequest input);
}
// Query
public interface IRequest { }
public interface IResponse<T> where T : IRequest { }
public interface IQueryHandler<in TRequest, out TResponse>
where TRequest : IRequest
where TResponse : IResponse<TRequest>
{
TResponse Handle(TRequest input);
}
public interface IGetUserByIdQueryHandler : IQueryHandler<GetUserByIdRequest, GetUserByIdResponse> { }
// QueryHandler
public class GetUserByIdRequest : IRequest { }
public class GetUserByIdResponse : IResponse<GetUserByIdRequest> { }
public class GetUserByIdQueryHandler : IGetUserByIdQueryHandler
{
public GetUserByIdResponse Handle(GetUserByIdRequest input)
{
return null;
}
}
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
// Register Services
var targetAssembly = typeof(Program).Assembly;
registerAllServiceOfAssembly(services, targetAssembly, targetAssembly);
});
// Interfaceとその実装クラス全てをDI Containerへ登録
static void registerAllServiceOfAssembly(IServiceCollection serviceCollection,
Assembly interfaceOfAssembly,
Assembly classofAssembly)
{
var interfaces = interfaceOfAssembly.ExportedTypes
.Where(w => w.IsInterface && !w.IsGenericType)
.Select(_ => _);
var classes = classofAssembly.ExportedTypes
.Where(w => w.IsClass).Select(_ => _);
var services = from i in interfaces
from c in classes
where c.GetInterface(i.Name) != null
select (InterfaceType: i, ClassType: c);
foreach (var s in services)
serviceCollection.AddTransient(s.InterfaceType, s.ClassType);
}
// 指定したInterfaceの実装クラスのみDI Containerへ登録
static void registerClasses(IServiceCollection serviceCollection, Assembly classOfAssembly, Type baseInterface)
{
var classes = classOfAssembly.ExportedTypes
.Where(w => w.GetInterface(baseInterface.Name) != null)
.Select(_ => _);
if (!classes.Any())
throw new Exception($"Not found exntended class of {baseInterface.Name} in {classOfAssembly.FullName} assembly.");
foreach (var c in classes)
serviceCollection.AddSingleton(baseInterface, c);
}
// 指定したGenericなInterfaceの実装クラスをDI Containerへ登録
static void registerGenericClasses(IServiceCollection serviceCollection, Assembly classOfAssembly, Type genericType)
{
// Predicate extended GenericClass
Predicate<Type> isExtendedGenericClass = p =>
{
return p.GetInterfaces().Any(a => a.IsGenericType && a.GetGenericTypeDefinition() == genericType);
};
var interfaces = genericType.Assembly.ExportedTypes
.Where(w => isExtendedGenericClass(w) && w.IsInterface).Select(_ => _);
var classes = classOfAssembly.ExportedTypes
.Where(w => isExtendedGenericClass(w) && w.IsClass).Select(_ => _);
var services = from i in interfaces
from c in classes
where c.GetInterface(i.Name) != null
select (InterfaceType: i, ClassType: c);
if (!services.Any())
throw new Exception($"Not found GenericTpye Class of {genericType.Name} in {classOfAssembly.FullName} assembly.");
foreach (var s in services)
serviceCollection.AddTransient(s.InterfaceType, s.ClassType);
}
}
public class Worker : BackgroundService
{
private readonly IGetUserByIdQueryHandler _getUserByIdQuery;
public Worker(IGetUserByIdQueryHandler getUserByIdQuery)
{
_getUserByIdQuery = getUserByIdQuery;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Query
var _ = _getUserByIdQuery.Handle(new GetUserByIdRequest());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment