/// <summary> /// Creates a new instance of this class /// </summary> /// <exception cref="InvalidGenericTypeException">Indicates that the passed generic type is not a valid class</exception> public ClassBridge() { if (!GenericType.IsClass) { throw new InvalidGenericTypeException(); } lock (Lock) { if (Methods == null) { Methods = GenericType.GetMethods() .Where( info => info.IsPublic && !info.IsGenericMethod) .ToDictionary(info => info, info => info.GetParameters()); } if (Constructors == null) { Constructors = GenericType.GetConstructors() .Where( info => info.IsPublic && !info.IsGenericMethod) .ToDictionary(info => info, info => info.GetParameters()); } if (Properties == null) { Properties = GenericType.GetProperties() .Where( info => Methods.ContainsKey(info.GetGetMethod()) || Methods.ContainsKey(info.GetSetMethod())) .ToList(); } if (Fields == null) { Fields = GenericType.GetFields().Where(info => info.IsPublic).ToList(); } if (Events == null) { Events = GenericType.GetEvents() .Where( info => Methods.ContainsKey(info.GetAddMethod()) && Methods.ContainsKey(info.GetRemoveMethod())) .ToList(); } foreach ( var info in Events.Where(info => info.GetAddMethod().IsStatic || info.GetRemoveMethod().IsStatic)) { var eventInvokerReturn = info.EventHandlerType.GetMethod("Invoke").ReturnType; if ((eventInvokerReturn == typeof(void)) || (eventInvokerReturn == typeof(object))) { var del = ClassBridge.CreateProxyDelegateForEvent(info, null, RaiseEvent); StaticEventsDelegates.Add(info, del); info.AddEventHandler(null, del); } else { var del = ClassBridge.CreateProxyDelegateForEvent(info, null, (instance, eventName, isVoid, eventArgs) => ClassBridge.NormalizeVariable(RaiseEvent(instance, eventName, isVoid, eventArgs), eventInvokerReturn, false)); StaticEventsDelegates.Add(info, del); info.AddEventHandler(null, del); } } if (SubEnumerations == null) { SubEnumerations = GenericType.GetNestedTypes(BindingFlags.Public) .Where(type => type.IsEnum) .Select(EnumBridge.FromType) .ToList(); foreach (var subEnum in SubEnumerations) { subEnum.PushJavascript += (sender, args) => OnPushJavascript(args); } } if (SubClasses == null) { SubClasses = GenericType.GetNestedTypes(BindingFlags.Public) .Where(type => type.IsClass && !typeof(Delegate).IsAssignableFrom(type)) .Select(ClassBridge.FromType) .ToList(); foreach (var subClasses in SubClasses) { subClasses.PushJavascript += (sender, args) => OnPushJavascript(args); } } } }
/// <summary> /// Registers an instance of the generic type and adds it to the list of registered instances /// </summary> /// <param name="instance">The instance of the generic type to ad</param> /// <param name="variableName">The name of the variable that is accessible from the Javascript side</param> /// <returns>Returns <see langword="this" /> instance to be used for other operations</returns> public virtual ClassBridge <T> AddInstance(T instance, string variableName) { if (instance != null) { if (!Instances.ContainsKey(instance)) { Instances.Add(instance, new List <string>()); if (!InstancesEventsDelegates.ContainsKey(instance)) { InstancesEventsDelegates.Add(instance, new Dictionary <EventInfo, Delegate>()); } foreach ( var info in Events.Where(info => !info.GetAddMethod().IsStatic&& !info.GetRemoveMethod().IsStatic)) { var eventDelegate = InstancesEventsDelegates[instance].FirstOrDefault(pair => pair.Key == info).Value; if (eventDelegate == null) { var eventInvokerReturn = info.EventHandlerType.GetMethod("Invoke").ReturnType; if ((eventInvokerReturn == typeof(void)) || (eventInvokerReturn == typeof(object))) { eventDelegate = ClassBridge.CreateProxyDelegateForEvent(info, instance, RaiseEvent); } else { eventDelegate = ClassBridge.CreateProxyDelegateForEvent(info, instance, (o, s, arg3, arg4) => ClassBridge.NormalizeVariable(RaiseEvent(o, s, arg3, arg4), eventInvokerReturn, false)); } InstancesEventsDelegates[instance].Add(info, eventDelegate); } info.AddEventHandler(instance, eventDelegate); } OnPushJavascript( new FireJavascriptEventArgs(ClassBridge.GenerateInstanceChange(Identification, GlobalPool.GetInstanceId(instance), false))); } } if (!string.IsNullOrWhiteSpace(variableName)) { foreach ( var key in Instances.Keys.Where(key => key != instance) .Where(key => Instances[key].Contains(variableName)) .ToArray()) { RemoveInstance(variableName, key as T); } if (instance != null) { if (!Instances[instance].Contains(variableName)) { Instances[instance].Add(variableName); OnPushJavascript( new FireJavascriptEventArgs(ClassBridge.GenerateInstanceVariable(Identification, GlobalPool.GetInstanceId(instance), variableName))); } } else { OnPushJavascript( new FireJavascriptEventArgs(ClassBridge.GenerateInstanceVariable(Identification, null, variableName))); } } return(this); }