从字符串接口用作通用类型

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);
}

最终编辑:这绝对是您想要做的吗?我会非常犹豫是否将这样的代码放在野外。