/// <summary> /// Gets table of operations for specific type. /// /// </summary> /// <param name="type"></param> /// <returns></returns> /// <remarks> /// Considers reflection costly operation and caching is optimization. Considers types unchangeable during runtime. /// </remarks> public static DispatchTable GetOperations(Type type) { DispatchTable table; if (!Cache.TryGetValue(type, out table)) { var ops = DipatchTableHelper.GetAllServiceImplementations(type); var newTable = createOperations(ops); lock (Cache) { if (!Cache.TryGetValue(type, out table)) { Cache[type] = newTable; table = newTable; } } } return(table); }
private static TypeBuilder GenerateProxyType(Type service) { var assemblyName = new AssemblyName(PREFIX + "DynamicAssembly"); AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder module = assembly.DefineDynamicModule(PREFIX + "EmittedModule"); //infertype name and fix generics string typeName = service.Name.Replace("[", String.Empty) .Replace("]", string.Empty) .Replace("`", string.Empty); typeName += DateTime.Now.Ticks; //TypeBuilder myHelloWorldType = module.DefineType(PREFIX + typeName, TypeAttributes.Public); TypeBuilder proxy = module.DefineType(PREFIX + typeName, TypeAttributes.Public, typeof(Object), new[] { service }); // Implement 'IMyInterface' interface. proxy.AddInterfaceImplementation(service); var methods = DipatchTableHelper.GetAllImplementations(service); foreach (var methodInfo in methods) { // Define the HelloMethod of IMyInterface. MethodBuilder myHelloMethod = proxy.DefineMethod(methodInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual, methodInfo.ReturnType, methodInfo.GetParameters() .Select(x => x.ParameterType) .ToArray()); // Generate IL for the method. ILGenerator myMethodIL = myHelloMethod.GetILGenerator(); //TODO: make use of RPC myMethodIL.ThrowException(typeof(Exception)); proxy.DefineMethodOverride(myHelloMethod, methodInfo); } return(proxy); }