如何根据类型名称从 ServiceProvider 获取 class 的实例
How to get an instance of a class from ServiceProvider from name of the type
我必须能够将 class 的名称作为 String
并使用该名称从应用程序的 IServiceProvider
集合中提取适当 class。将要创建的 classes 在应用程序启动时全部注入到 IServiceCollection
中,并将其他服务注入到它们的构造函数中。
如果我们假设访问由对 Assembly.GetExportedTypes()
的各种调用构造的类型列表,我可以使用
之类的东西获得我需要的 Type
var type = myListOfServices.FirstOrDefault(_=>_.FullName == "My.Qualified.ClassName");
我可以使用
获取服务实例
var instance = serviceProvider.GetService(type);
问题是 instance
是 object
类型,我不知道如何将其转换为 actual 类型以便我可以访问它的属性和方法。
更新
我想创建的 classes 具有我需要能够调用的方法,因此,我需要能够将 GetService()
返回的 object
转换为特定的键入以便我可以访问这些方法。
虽然我在变量中有类型(请参阅上面的示例),但您不能使用该变量来区分对象...
var attempt1 = (type)instance; // won't compile
var attempt2 = instance as type; // won't compile
关键是我试图获取的实例可能是任意数量的 classes 之一,但我所知道的只是名称(这是作为字符串消息提供的)
How to cast Object to its actual type? 的建议不合适,因为那里的答案假设你知道类型,我必须在运行时计算出类型
无论如何,如果你使用 DI 或其他任何东西,如果你只有一个字符串并且需要获取相应的实例,则此方法始终只能 return object
类型的东西 compile-time。在那种情况下,你有这样的东西:
public object GetInstanceFromType(string qualifiedClassName)
{
// ... get desired instance from given parameter
}
下一步实际上取决于所需的灵活性。所有可以被该函数 return 编辑的 class 是否共享一个公共接口或基础 class?如果是,您可以将上述方法的 return 值更改为 return 该接口或基础 class 并将动态找到的实例转换为那个东西,在这种情况下您可以调用所有方法/ 来自指定接口的属性 / base class:
public ICommonInterface GetInstanceFromType(string qualifiedClassName)
{
// ...get desired instance from given parameter
return (ICommonInterface)instanceFound;
}
如果这不起作用,您可以切换到策略模式。在那种情况下,您测试当前实例是哪种类型,将其转换为它,然后调用所需的方法:
var instanceFound = GetInstanceFromType("My.Qualified.ClassName");
switch (instanceFound)
{
case SpecificClassOne sco:
sco.DoSomething();
break;
case SpecificClassTwo sct:
sct.DoSomethingElse();
break;
default:
throw new InvalidOperationException($"Type {instanceFound.GetType()} can't be handled.");
}
我必须能够将 class 的名称作为 String
并使用该名称从应用程序的 IServiceProvider
集合中提取适当 class。将要创建的 classes 在应用程序启动时全部注入到 IServiceCollection
中,并将其他服务注入到它们的构造函数中。
如果我们假设访问由对 Assembly.GetExportedTypes()
的各种调用构造的类型列表,我可以使用
Type
var type = myListOfServices.FirstOrDefault(_=>_.FullName == "My.Qualified.ClassName");
我可以使用
获取服务实例var instance = serviceProvider.GetService(type);
问题是 instance
是 object
类型,我不知道如何将其转换为 actual 类型以便我可以访问它的属性和方法。
更新
我想创建的 classes 具有我需要能够调用的方法,因此,我需要能够将 GetService()
返回的 object
转换为特定的键入以便我可以访问这些方法。
虽然我在变量中有类型(请参阅上面的示例),但您不能使用该变量来区分对象...
var attempt1 = (type)instance; // won't compile
var attempt2 = instance as type; // won't compile
关键是我试图获取的实例可能是任意数量的 classes 之一,但我所知道的只是名称(这是作为字符串消息提供的)
How to cast Object to its actual type? 的建议不合适,因为那里的答案假设你知道类型,我必须在运行时计算出类型
无论如何,如果你使用 DI 或其他任何东西,如果你只有一个字符串并且需要获取相应的实例,则此方法始终只能 return object
类型的东西 compile-time。在那种情况下,你有这样的东西:
public object GetInstanceFromType(string qualifiedClassName)
{
// ... get desired instance from given parameter
}
下一步实际上取决于所需的灵活性。所有可以被该函数 return 编辑的 class 是否共享一个公共接口或基础 class?如果是,您可以将上述方法的 return 值更改为 return 该接口或基础 class 并将动态找到的实例转换为那个东西,在这种情况下您可以调用所有方法/ 来自指定接口的属性 / base class:
public ICommonInterface GetInstanceFromType(string qualifiedClassName)
{
// ...get desired instance from given parameter
return (ICommonInterface)instanceFound;
}
如果这不起作用,您可以切换到策略模式。在那种情况下,您测试当前实例是哪种类型,将其转换为它,然后调用所需的方法:
var instanceFound = GetInstanceFromType("My.Qualified.ClassName");
switch (instanceFound)
{
case SpecificClassOne sco:
sco.DoSomething();
break;
case SpecificClassTwo sct:
sct.DoSomethingElse();
break;
default:
throw new InvalidOperationException($"Type {instanceFound.GetType()} can't be handled.");
}