在 startup.cs 中动态注册服务
dynamically register services in startup.cs
我正在尝试在 startup.cs 中动态注册服务。我在从动态类型对象调用方法时遇到问题。
步骤
- 用方法创建界面;
public interface ICustBillTypeService
{ public static void RegisterTypeServices(IServiceCollection services) { } }
- 从界面创建 class。方法接受
ServiceCollection
并添加适当的 ServiceDescriptor
.
public class RPT628Registration : ICustBillTypeService
{
public static void RegisterTypeServices(IServiceCollection services)
{ services.AddScoped<RPT628Service>();}
}
- 识别程序集中实现
ICustBillTypeService
和 return class 名字。
var results = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => typeof(ICustBillEntityService).IsAssignableFrom(x)
&& !x.IsInterface
&& !x.IsAbstract)
.Select(x => x.Name).ToList();
- 对于每个找到的class,调用class实现的接口方法将服务添加到ServiceCollection
这就是我 运行 遇到问题的地方。第 3 步 returns 实现该接口的所有类型的名称。我可以遍历每个结果,确定类型并创建该类型的实例,但我无法访问 class 的方法,因为我的对象是在运行时动态类型化的,只能访问基础对象定义
foreach(var result in results)
{
Type resultType = Type.GetType(result);
var t = Activator.CreateInstance(resultType);
--> t.RegisterTypeServices(services); //fails the build because the method is not part of the object until run time.
}
我不想调用方法的“字符串”名称。无论如何,是否可以利用带有“t”的接口,以便我可以调用方法名称?
在写这篇文章的时候,我想通了。它确实需要将方法名称作为字符串传入,但我可以接受。
/// Add "GetTypeServices(services)" to ConfigureServices in Startup.cs;
public void GetTypeServices(IServiceCollection services)
{
var results = Assembly.GetExecutingAssembly().GetTypes()
.Where(x => typeof(ICustBillTypeService).IsAssignableFrom(x)
&& !x.IsInterface
&& !x.IsAbstract)
.Select(x => x.FullName).ToList();
foreach(var result in results)
{
Type resultType = Type.GetType(result);
MethodInfo typeMethod = resultType.GetMethod("RegisterTypeServices");
var t = Activator.CreateInstance(resultType);
dynamic methodResult = typeMethod.Invoke(t, new object[] { services });
}
}
现在 Startup.cs 当我们需要添加新服务时不必修改。开发者只要创建一个新的class继承该接口,就会自动被发现
我正在尝试在 startup.cs 中动态注册服务。我在从动态类型对象调用方法时遇到问题。
步骤
- 用方法创建界面;
public interface ICustBillTypeService
{ public static void RegisterTypeServices(IServiceCollection services) { } }
- 从界面创建 class。方法接受
ServiceCollection
并添加适当的ServiceDescriptor
.
public class RPT628Registration : ICustBillTypeService
{
public static void RegisterTypeServices(IServiceCollection services)
{ services.AddScoped<RPT628Service>();}
}
- 识别程序集中实现
ICustBillTypeService
和 return class 名字。
var results = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => typeof(ICustBillEntityService).IsAssignableFrom(x)
&& !x.IsInterface
&& !x.IsAbstract)
.Select(x => x.Name).ToList();
- 对于每个找到的class,调用class实现的接口方法将服务添加到ServiceCollection 这就是我 运行 遇到问题的地方。第 3 步 returns 实现该接口的所有类型的名称。我可以遍历每个结果,确定类型并创建该类型的实例,但我无法访问 class 的方法,因为我的对象是在运行时动态类型化的,只能访问基础对象定义
foreach(var result in results)
{
Type resultType = Type.GetType(result);
var t = Activator.CreateInstance(resultType);
--> t.RegisterTypeServices(services); //fails the build because the method is not part of the object until run time.
}
我不想调用方法的“字符串”名称。无论如何,是否可以利用带有“t”的接口,以便我可以调用方法名称?
在写这篇文章的时候,我想通了。它确实需要将方法名称作为字符串传入,但我可以接受。
/// Add "GetTypeServices(services)" to ConfigureServices in Startup.cs;
public void GetTypeServices(IServiceCollection services)
{
var results = Assembly.GetExecutingAssembly().GetTypes()
.Where(x => typeof(ICustBillTypeService).IsAssignableFrom(x)
&& !x.IsInterface
&& !x.IsAbstract)
.Select(x => x.FullName).ToList();
foreach(var result in results)
{
Type resultType = Type.GetType(result);
MethodInfo typeMethod = resultType.GetMethod("RegisterTypeServices");
var t = Activator.CreateInstance(resultType);
dynamic methodResult = typeMethod.Invoke(t, new object[] { services });
}
}
现在 Startup.cs 当我们需要添加新服务时不必修改。开发者只要创建一个新的class继承该接口,就会自动被发现