从字符串接口用作通用类型
Interface from string to use as generic type
我在 Azure 中使用 Service Fabric 并设置了这样一个参与者的代理:
var proxy = ActorProxy.Create<T>(actorId);
其中 T 必须指定为我正在调用的 actor 的接口。
假设我有一个字符串形式的接口名称:
var interfaceName = "IUserActor";
有没有办法通过这个字符串名称实例化泛型?如果有,我如何通过它的字符串名称调用给定接口中指定的方法?
所有参与者接口都继承自 IActor,它是 Service Fabric 的一部分。
现在我明白不推荐这样做,重点是能够从测试和管理目的访问给定 actor 的 actor 状态。在这种情况下,速度无关紧要,因此任何反射方法都可以。
所以,一个基本的用法示例,不使用动态接口名称:
public async Task<string> AdminGetState(ActorId actorId, string interfaceName){
var proxy = ActorProxy.Create<IUserActor>(actorId);
var state = await proxy.AdminGetStateJson();
return JsonConvert.SerializeObject(state);
}
它不漂亮或效率不高,但您可以使用反射来做到这一点...
public async Task<string> AdminGetState(ActorId actorId, string interfaceName){
//Find the type information for "interfaceName". (Assuming it's in the executing assembly)
var interfaceType = Assembly.GetExecutingAssembly().GetType(interfaceName);
//Use reflection to get the Create<> method, and generify it with this type
var createMethod = typeof(ActorProxy).GetMethod(nameof(ActorProxy.Create)).MakeGenericMethod(interfaceType);
//Invoke the dynamically reflected method, passing null as the first argument because it's static
object proxy = createMethod.Invoke(null,new object[] { actorId });
//As per your comments, find the "AdminGetStateJson" method here. You're REALLY trusting that it exists at this point.
var adminGetStateMethod = interfaceType.GetMethod("AdminGetStateJson");
Task<string> stateTask = (Task<string>)adminGetStateMethod.Invoke(proxy, null);
var state = await stateTask;
return JsonConvert.SerializeObject(state);
}
最终编辑:这绝对是您想要做的吗?我会非常犹豫是否将这样的代码放在野外。
我在 Azure 中使用 Service Fabric 并设置了这样一个参与者的代理:
var proxy = ActorProxy.Create<T>(actorId);
其中 T 必须指定为我正在调用的 actor 的接口。
假设我有一个字符串形式的接口名称:
var interfaceName = "IUserActor";
有没有办法通过这个字符串名称实例化泛型?如果有,我如何通过它的字符串名称调用给定接口中指定的方法?
所有参与者接口都继承自 IActor,它是 Service Fabric 的一部分。
现在我明白不推荐这样做,重点是能够从测试和管理目的访问给定 actor 的 actor 状态。在这种情况下,速度无关紧要,因此任何反射方法都可以。
所以,一个基本的用法示例,不使用动态接口名称:
public async Task<string> AdminGetState(ActorId actorId, string interfaceName){
var proxy = ActorProxy.Create<IUserActor>(actorId);
var state = await proxy.AdminGetStateJson();
return JsonConvert.SerializeObject(state);
}
它不漂亮或效率不高,但您可以使用反射来做到这一点...
public async Task<string> AdminGetState(ActorId actorId, string interfaceName){
//Find the type information for "interfaceName". (Assuming it's in the executing assembly)
var interfaceType = Assembly.GetExecutingAssembly().GetType(interfaceName);
//Use reflection to get the Create<> method, and generify it with this type
var createMethod = typeof(ActorProxy).GetMethod(nameof(ActorProxy.Create)).MakeGenericMethod(interfaceType);
//Invoke the dynamically reflected method, passing null as the first argument because it's static
object proxy = createMethod.Invoke(null,new object[] { actorId });
//As per your comments, find the "AdminGetStateJson" method here. You're REALLY trusting that it exists at this point.
var adminGetStateMethod = interfaceType.GetMethod("AdminGetStateJson");
Task<string> stateTask = (Task<string>)adminGetStateMethod.Invoke(proxy, null);
var state = await stateTask;
return JsonConvert.SerializeObject(state);
}
最终编辑:这绝对是您想要做的吗?我会非常犹豫是否将这样的代码放在野外。