Example #1
0
        /// <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)));
        }
Example #2
0
        /// <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>));
        }