我已经为SOAP和REST编写了动态Web服务。现在需要创建OData Web服务,该服务具有根据WCF数据服务规范返回IQueryable接口的操作。 我正在创建一个基于IL Emit语句的动态方法。但是我无法将返回类型分配给IQueryable的MethodBuilder。
具体来说,我无法使用MethodBuilder.SetReturnType方法设置返回参数,因为返回类型IQueryable是在运行时生成的。
public class MainClass
{
public static void Main()
{
AssemblyBuilder serviceAsmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyDynamicAsm"), AssemblyBuilderAccess.RunAndSave);
ModuleBuilder serviceModule = serviceAsmBuilder.DefineDynamicModule("MyDynamicAsm", "MyDynamicAsm.dll");
TypeBuilder serviceTypeBuilder = serviceModule.DefineType("MyDynamicType", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass,
typeof(DataService<WebServerResult>) );
//This is the problem, as I do not have this class at compile
//time. I get this class at run time
Type returnType = typeof(IQueryable<WebServerResult>);
MethodBuilder MethodBldr = serviceTypeBuilder.DefineMethod("OperationName", MethodAttributes.Public, returnType, Type.EmptyTypes);
ILGenerator methodGenerator = MethodBldr.GetILGenerator();
methodGenerator.Emit(OpCodes.Ret);
}
}
//This is just for reference. This code does not exist at design time
[DataContract]
public class WebServerResult
{
[DataMember]
public List<Variable> Variables { get; set; }
public IQueryable<Variable> ODataResultList
{
get { return Variables.AsQueryable<Variable>(); }
}
}
[DataServiceKey("VariableName")]
[DataContract(Namespace = "")]
public class Variable
{
[DataMember]
public string VariableName { get; set; }
[DataMember]
public string VariableValue { get; set; }
[DataMember]
public string VariableType { get; set; }
}
有人能为我提供IL发射代码中方法生成的蓝图吗?
答案 0 :(得分:2)
要创建包含在运行时之前未知的类型参数的泛型类型,您必须使用Type.MakeGenericType方法。您的代码可能如下所示:
//get the dynamic type from somewhere
Type unknownType = ...;
//get open generic base type
Type openGeneric = typeof(IQueryable<>);
//create closed generic type with the unknown type as generic type parameter
Type closedGeneric = openGeneric.MakeGenericType(unknownType);
//use the closed type for whatever you want
Type returnType = closedGeneric;