예제 #1
0
        public DynamicTypeBuilder ConfigureConstructor()
        {
            var constructors = InstanceType.GetTypeInfo().GetConstructors();

            if (constructors.Length > 1)
            {
                Array.Sort(constructors, (ctor1, ctor2) => ctor2.GetParameters().Length - ctor1.GetParameters().Length);
                VerifyConstructorParameters();
            }

            var ctor                   = constructors[0];
            var parameterInfos         = ctor.GetParameters();
            var originalParameterCount = parameterInfos.Length;
            var parameterTypes         = new Type[originalParameterCount + 1];

            Array.Copy(parameterInfos.Select(p => p.ParameterType).ToArray(), parameterTypes, originalParameterCount);
            parameterTypes[originalParameterCount] = typeof(IServiceProvider);

            var constructorBuilder =
                _typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes);
            var il = constructorBuilder.GetILGenerator();

            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldarg_0);
            for (var i = 1; i <= originalParameterCount; i++)
            {
                il.Emit(OpCodes.Ldarg, i);
            }
            il.Emit(OpCodes.Newobj, ctor);
            il.Emit(OpCodes.Stfld, InstanceFieldFeature.FieldBuilder);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg, originalParameterCount + 1);
            il.Emit(OpCodes.Stfld, ServicesFeature.FieldBuilder);
            il.Emit(OpCodes.Ret);

            InstanceConstructorFeatures = new ConstructorFeature()
            {
                ConstructorBuilder = constructorBuilder,
                ConstructorInfo    = ctor
            };

            return(this);

            void VerifyConstructorParameters()
            {
                var firstCtor        = constructors[0];
                var parameterTypeSet = firstCtor.GetParameters().Select(p => p.ParameterType).ToImmutableHashSet();

                for (int i = 1; i < constructors.Length; i++)
                {
                    if (!parameterTypeSet.IsSupersetOf(constructors[i].GetParameters().Select(p => p.ParameterType)))
                    {
                        throw new InvalidOperationException("当构造函数不唯一时,必须有一个构造函数的参数是其他构造函数参数的超集");
                    }
                }
            }
        }
예제 #2
0
        public GeneralSubscribable(object instance)
        {
            Instance         = instance;
            InstanceType     = instance.GetType();
            InstanceTypeInfo = InstanceType.GetTypeInfo();

            NotifyPropertyChanged = instance as INotifyPropertyChanged;
            HookIntoChangeHandlers();
        }
예제 #3
0
        public async Task <bool> AttachEvent(string eventName, EventHandler <HtmlEventArgs> handler)
        {
            if (string.IsNullOrEmpty(eventName))
            {
                throw new ArgumentNullException("eventName");
            }

            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }

            var scriptAlias = eventName;
            var ei          = InstanceType.GetTypeInfo().GetEvent(eventName, BindingFlags.Instance | BindingFlags.Public);

            if (ei != null)
            {
                if (ei.IsDefined(typeof(ScriptableMemberAttribute), false))
                {
                    var att = ei.GetCustomAttribute <ScriptableMemberAttribute>(false);
                    scriptAlias = (att.ScriptAlias ?? scriptAlias);
                }
            }

            WebSharpHtmlEvent websharpEvent;
            var result = false;

            if (!EventHandlers.TryGetValue(scriptAlias, out websharpEvent))
            {
                websharpEvent = new WebSharpHtmlEvent(this, scriptAlias);
                if (ScriptObjectProxy != null)
                {
                    var eventCallback = new
                    {
                        handle      = Handle,
                        onEvent     = scriptAlias,
                        uid         = websharpEvent.UID,
                        callback    = websharpEvent.EventCallbackFunction,
                        handlerType = "HtmlEventArgs"
                    };

                    result = await WebSharp.Bridge.AddEventListener(eventCallback);
                }
                EventHandlers[scriptAlias] = websharpEvent;
            }
            websharpEvent.AddEventHandler(handler);
            return(result);
        }