protected override void AddInterfaces()
 {
     base.AddInterfaces();
     Tb.AddInterfaceImplementation(typeof(IReadonlyConfiguration));
 }
Exemplo n.º 2
0
 protected virtual void AddRealtimeImplementation() => Tb.AddInterfaceImplementation(typeof(IRealtimeConfiguration));
        protected virtual void AddInpcImplementation()
        {
            // todo: refactor this method?

            Tb.AddInterfaceImplementation(typeof(INotifyPropertyChanged));
            Tb.AddInterfaceImplementation(typeof(INotifyingConfiguration));

            var field = Tb.DefineField(
                "PropertyChanged",
                typeof(PropertyChangedEventHandler),
                FieldAttributes.Private);

            var eventInfo = Tb.DefineEvent(
                "PropertyChanged",
                EventAttributes.None,
                typeof(PropertyChangedEventHandler));

            {
                var ibaseMethod = typeof(INotifyPropertyChanged).GetMethod("add_PropertyChanged");
                Debug.Assert(ibaseMethod != null, nameof(ibaseMethod) + " != null");

                var addMethod = Tb.DefineMethod("add_PropertyChanged",
                                                ibaseMethod.Attributes ^ MethodAttributes.Abstract,
                                                ibaseMethod.CallingConvention,
                                                ibaseMethod.ReturnType,
                                                new[] { typeof(PropertyChangedEventHandler) });

                var combine = typeof(Delegate).GetMethod("Combine", new[] { typeof(Delegate), typeof(Delegate) });
                Debug.Assert(combine != null, nameof(combine) + " != null");

                var generator = addMethod.GetILGenerator();
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldfld, field);
                generator.Emit(OpCodes.Ldarg_1);
                generator.Emit(OpCodes.Call, combine);
                generator.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
                generator.Emit(OpCodes.Stfld, field);
                generator.Emit(OpCodes.Ret);
                eventInfo.SetAddOnMethod(addMethod);
            }

            {
                var ibaseMethod = typeof(INotifyPropertyChanged).GetMethod("remove_PropertyChanged");
                Debug.Assert(ibaseMethod != null, nameof(ibaseMethod) + " != null");

                var removeMethod = Tb.DefineMethod("remove_PropertyChanged",
                                                   ibaseMethod.Attributes ^ MethodAttributes.Abstract,
                                                   ibaseMethod.CallingConvention,
                                                   ibaseMethod.ReturnType,
                                                   new[] { typeof(PropertyChangedEventHandler) });
                var remove = typeof(Delegate).GetMethod("Remove", new[] { typeof(Delegate), typeof(Delegate) });
                Debug.Assert(remove != null, nameof(remove) + " != null");

                var generator = removeMethod.GetILGenerator();
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldfld, field);
                generator.Emit(OpCodes.Ldarg_1);
                generator.Emit(OpCodes.Call, remove);
                generator.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
                generator.Emit(OpCodes.Stfld, field);
                generator.Emit(OpCodes.Ret);
                eventInfo.SetRemoveOnMethod(removeMethod);
            }

            {
                var methodBuilder = Tb.DefineMethod("OnPropertyChanged",
                                                    MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig |
                                                    MethodAttributes.NewSlot, CallingConventions.HasThis, typeof(void),
                                                    new[] { typeof(string) });
                var generator   = methodBuilder.GetILGenerator();
                var returnLabel = generator.DefineLabel();
                generator.DeclareLocal(typeof(PropertyChangedEventHandler));
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldfld, field);
                generator.Emit(OpCodes.Ldarg_1);
                generator.Emit(OpCodes.Call, typeof(PropertyChangedInvoker).GetMethod("Invoke"));
                generator.MarkLabel(returnLabel);
                generator.Emit(OpCodes.Ret);
                eventInfo.SetRaiseMethod(methodBuilder);
                _onPropertyChangedMethod = methodBuilder.GetBaseDefinition();
            }
        }