/// <summary> /// Create dynamic method that instantiates given <c>realType</c> using constructor with given <c>types</c>. /// If given <c>realType</c> does not define wanted constructor, dynamic method that throws InvalidOperationException is created. /// </summary> /// <typeparam name="D">The typed delegate the create.</typeparam> /// <param name="realType">The type to be instantiated by dynamic method.</param> /// <param name="types">Types of parameters of wanted constructor to be called.</param> /// <returns>Delegate to dynamic method that creates specified type or throws an exception. The method cannot return null.</returns> private static Delegate /*!*/ BuildNewObj <D>(Type /*!*/ realType, Type[] types) where D : class { Debug.Assert(realType != null); ConstructorInfo ctor_info = realType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null); DynamicMethod method = new DynamicMethod(string.Format("<{0}>.ctor", realType.Name), Emit.Types.Object[0], types); Emit.ILEmitter il = new PHP.Core.Emit.ILEmitter(method); if (ctor_info != null) { // new T(arg1, arg2, ...); for (int i = 0; i < types.Length; ++i) { il.Ldarg(i); } il.Emit(OpCodes.Newobj, ctor_info); } else { var invalid_ctor = typeof(InvalidOperationException).GetConstructor(Type.EmptyTypes); Debug.Assert(invalid_ctor != null); // new InvalidOperationException(); il.Emit(OpCodes.Newobj, invalid_ctor); } // return il.Emit(OpCodes.Ret); // return(method.CreateDelegate(typeof(D))); }
/// <summary> /// Create DynamicMethod that configures capabilities using System.Web.Configuration.BrowserCapabilitiesFactory (or similar) type. /// </summary> /// <param name="BrowserCapabilitiesFactoryType">Type with ConfigureBrowserCapabilities and ConfigureCustomCapabilities methods.</param> /// <remarks> /// Generated method performs following code: /// { /// var capsFactory = new System.Web.Configuration.BrowserCapabilitiesFactory(); /// capsFactory.ConfigureBrowserCapabilities(headers, browserCaps); /// capsFactory.ConfigureCustomCapabilities(headers, browserCaps); /// } /// </remarks> private static Action<NameValueCollection, HttpBrowserCapabilities> BuildConfigureCapsMethod(Type/*!*/BrowserCapabilitiesFactoryType) { Debug.Assert(BrowserCapabilitiesFactoryType != null); var method_ctor = BrowserCapabilitiesFactoryType.GetConstructor(Type.EmptyTypes); var method_ConfigureBrowserCapabilities = BrowserCapabilitiesFactoryType.GetMethod("ConfigureBrowserCapabilities"); var method_ConfigureCustomCapabilities = BrowserCapabilitiesFactoryType.GetMethod("ConfigureCustomCapabilities"); if (method_ctor == null) throw new InvalidOperationException(string.Format("{0} does not implement .ctor.", BrowserCapabilitiesFactoryType.ToString())); if (method_ConfigureBrowserCapabilities == null) throw new InvalidOperationException(string.Format("{0} does not implement {1}.", BrowserCapabilitiesFactoryType.ToString(), "ConfigureBrowserCapabilities")); if (method_ConfigureCustomCapabilities == null) throw new InvalidOperationException(string.Format("{0} does not implement {1}.", BrowserCapabilitiesFactoryType.ToString(), "ConfigureCustomCapabilities")); var method = new DynamicMethod("<dynamic>.BrowserCapabilitiesFactory", typeof(void), new Type[] { typeof(NameValueCollection), typeof(HttpBrowserCapabilities) }); var il = new PHP.Core.Emit.ILEmitter(method); method.DefineParameter(1, System.Reflection.ParameterAttributes.None, "headers"); method.DefineParameter(2, System.Reflection.ParameterAttributes.None, "browserCaps"); // var capsFactory = new System.Web.Configuration.BrowserCapabilitiesFactory(); var loc_factory = il.DeclareLocal(BrowserCapabilitiesFactoryType); il.Emit(OpCodes.Newobj, method_ctor); il.Stloc(loc_factory); // capsFactory.ConfigureBrowserCapabilities(headers, browserCaps); il.Ldloc(loc_factory); il.Ldarg(0); il.Ldarg(1); il.Emit(OpCodes.Callvirt, method_ConfigureBrowserCapabilities); // capsFactory.ConfigureCustomCapabilities(headers, browserCaps); il.Ldloc(loc_factory); il.Ldarg(0); il.Ldarg(1); il.Emit(OpCodes.Callvirt, method_ConfigureCustomCapabilities); // ret il.Emit(OpCodes.Ret); // done return (Action<NameValueCollection, HttpBrowserCapabilities>)method.CreateDelegate(typeof(Action<NameValueCollection, HttpBrowserCapabilities>)); }