是否可以通过循环添加所有 IHostedService 类 (ASP.NET Core 6)?
Is it possible to add all IHostedService classes with a loop (ASP.NET Core 6)?
是否可以在循环中添加所有 IHostedService
实现的 类 而无需在 ASP.NET Core 6 中单独添加它们?
假设我们有这两个实现:
public class FirstImplementationOfHostedService : IHostedService
{
// ...
}
public class SecondImplementationOfHostedService : IHostedService
{
// ...
}
Program.cs
中的默认添加方式是:
builder.Services.AddHostedService<FirstImplementationOfHostedService>();
builder.Services.AddHostedService<SecondImplementationOfHostedService>();
但是,如果有一百个实现呢?
必须有更好的方法来添加(在运行时)Program.cs
中的一百个实现,而无需明确拼出它们的所有名称!
你可以使用 scrutor 进行程序集扫描(这似乎是你想要的)https://andrewlock.net/using-scrutor-to-automatically-register-your-services-with-the-asp-net-core-di-container/
您可以使用像 this 这样的 nuget 包,或者您可以创建一个扩展方法并通过反射获取所有服务引用:
public static class ServiceCollectionExtensions
{
public static void RegisterAllTypes<T>(this IServiceCollection services,
Assembly[] assemblies,
ServiceLifetime lifetime = ServiceLifetime.Transient)
{
var typesFromAssemblies = assemblies.SelectMany(a =>
a.DefinedTypes.Where(x => x.GetInterfaces().Contains(typeof(T))));
foreach (var type in typesFromAssemblies)
services.Add(new ServiceDescriptor(typeof(T), type, lifetime));
}
}
然后在 startup.cs
调用它
public void ConfigureServices(IServiceCollection services)
{
// ....
services.RegisterAllTypes<IInvoicingService>(new[] { typeof(Startup).Assembly });
}
但请注意,您是在集合中注册服务。有一个长版本的答案 here。你应该检查一下。
@nzrytmn 的回答完全有效。非常感谢!
我刚刚在 RegisterAllTypes
中做了一些调整以满足我自己的要求:
public static void RegisterAllTypes<T>(this IServiceCollection services)
{
var assemblies = new[] { Assembly.GetEntryAssembly() };
var typesFromAssemblies = assemblies.SelectMany(a => a?.DefinedTypes.Where(x => x.GetInterfaces().Contains(typeof(T))));
foreach (var type in typesFromAssemblies)
services.Add(new ServiceDescriptor(typeof(T), type, ServiceLifetime.Singleton));
}
然后在 Program.cs
:
builder.Services.RegisterAllTypes<IHostedService>();
是否可以在循环中添加所有 IHostedService
实现的 类 而无需在 ASP.NET Core 6 中单独添加它们?
假设我们有这两个实现:
public class FirstImplementationOfHostedService : IHostedService
{
// ...
}
public class SecondImplementationOfHostedService : IHostedService
{
// ...
}
Program.cs
中的默认添加方式是:
builder.Services.AddHostedService<FirstImplementationOfHostedService>();
builder.Services.AddHostedService<SecondImplementationOfHostedService>();
但是,如果有一百个实现呢?
必须有更好的方法来添加(在运行时)Program.cs
中的一百个实现,而无需明确拼出它们的所有名称!
你可以使用 scrutor 进行程序集扫描(这似乎是你想要的)https://andrewlock.net/using-scrutor-to-automatically-register-your-services-with-the-asp-net-core-di-container/
您可以使用像 this 这样的 nuget 包,或者您可以创建一个扩展方法并通过反射获取所有服务引用:
public static class ServiceCollectionExtensions
{
public static void RegisterAllTypes<T>(this IServiceCollection services,
Assembly[] assemblies,
ServiceLifetime lifetime = ServiceLifetime.Transient)
{
var typesFromAssemblies = assemblies.SelectMany(a =>
a.DefinedTypes.Where(x => x.GetInterfaces().Contains(typeof(T))));
foreach (var type in typesFromAssemblies)
services.Add(new ServiceDescriptor(typeof(T), type, lifetime));
}
}
然后在 startup.cs
调用它public void ConfigureServices(IServiceCollection services)
{
// ....
services.RegisterAllTypes<IInvoicingService>(new[] { typeof(Startup).Assembly });
}
但请注意,您是在集合中注册服务。有一个长版本的答案 here。你应该检查一下。
@nzrytmn 的回答完全有效。非常感谢!
我刚刚在 RegisterAllTypes
中做了一些调整以满足我自己的要求:
public static void RegisterAllTypes<T>(this IServiceCollection services)
{
var assemblies = new[] { Assembly.GetEntryAssembly() };
var typesFromAssemblies = assemblies.SelectMany(a => a?.DefinedTypes.Where(x => x.GetInterfaces().Contains(typeof(T))));
foreach (var type in typesFromAssemblies)
services.Add(new ServiceDescriptor(typeof(T), type, ServiceLifetime.Singleton));
}
然后在 Program.cs
:
builder.Services.RegisterAllTypes<IHostedService>();