private void EmbedRunningScripts(string name, EmbeddedType e) { embedded[name] = e; foreach (var s in scripts) { s.Engine.Global.DefineProperty( name, new PropertyDescriptor(e.Create(s), e.Attributes), true); } }
/// <summary> /// Creates a JavaScript value from an host type if the it does not already exist /// </summary> /// <param name="type">Host type</param> /// <returns>JavaScript value created from an host type</returns> public JsValue GetOrCreateScriptType(Type type) { if (!_embeddedTypeStorageInitialized) { lock (_embeddedTypeStorageInitializationSynchronizer) { if (!_embeddedTypeStorageInitialized) { _lazyEmbeddedTypes = new ConcurrentDictionary <string, Lazy <EmbeddedType> >(); _embeddedTypeFinalizeCallback = EmbeddedTypeFinalizeCallback; _embeddedTypeStorageInitialized = true; } } } string embeddedTypeKey = type.AssemblyQualifiedName; EmbeddedType embeddedType = _lazyEmbeddedTypes.GetOrAdd( embeddedTypeKey, key => new Lazy <EmbeddedType>(() => CreateEmbeddedType(type)) ).Value; return(embeddedType.ScriptValue); }
private EmbeddedType CreateEmbeddedType(Type type) { #if NET40 Type typeInfo = type; #else TypeInfo typeInfo = type.GetTypeInfo(); #endif string typeName = type.FullName; BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(true); ConstructorInfo[] constructors = type.GetConstructors(defaultBindingFlags); JsNativeFunction nativeConstructorFunction = (callee, isConstructCall, args, argCount, callbackData) => { object result; JsValue resultValue; object[] processedArgs = GetHostItemMemberArguments(args); if (processedArgs.Length == 0 && typeInfo.IsValueType) { result = Activator.CreateInstance(type); resultValue = MapToScriptType(result); return(resultValue); } if (constructors.Length == 0) { CreateAndSetError(string.Format(Strings.Runtime_HostTypeConstructorNotFound, typeName)); return(JsValue.Undefined); } var bestFitConstructor = (ConstructorInfo)ReflectionHelpers.GetBestFitMethod( constructors, processedArgs); if (bestFitConstructor == null) { CreateAndSetReferenceError(string.Format( Strings.Runtime_SuitableConstructorOfHostTypeNotFound, typeName)); return(JsValue.Undefined); } ReflectionHelpers.FixArgumentTypes(ref processedArgs, bestFitConstructor.GetParameters()); try { result = bestFitConstructor.Invoke(processedArgs); } catch (Exception e) { Exception exception = UnwrapException(e); var wrapperException = exception as WrapperException; JsValue errorValue = wrapperException != null? CreateErrorFromWrapperException(wrapperException) : JsErrorHelpers.CreateError(string.Format( Strings.Runtime_HostTypeConstructorInvocationFailed, typeName, exception.Message)) ; JsErrorHelpers.SetException(errorValue); return(JsValue.Undefined); } resultValue = MapToScriptType(result); return(resultValue); }; GCHandle embeddedTypeHandle = GCHandle.Alloc(type); IntPtr embeddedTypePtr = GCHandle.ToIntPtr(embeddedTypeHandle); JsValue objValue = JsValue.CreateExternalObject(embeddedTypePtr, _embeddedTypeFinalizeCallback); JsValue typeValue = JsValue.CreateFunction(nativeConstructorFunction); SetNonEnumerableProperty(typeValue, ExternalObjectPropertyName, objValue); var embeddedType = new EmbeddedType(type, typeValue, new List <JsNativeFunction> { nativeConstructorFunction }); ProjectFields(embeddedType); ProjectProperties(embeddedType); ProjectMethods(embeddedType); FreezeObject(typeValue); return(embeddedType); }
/// <summary> /// Initialises a new instance of the <see cref="HalJsonMediaTypeFormatter" /> class. /// </summary> /// <param name="embeddedType"> /// <see cref="EmbeddedType" /> value to be used during the serialisation. /// </param> public HalJsonMediaTypeFormatter(EmbeddedType embeddedType) : this() { this.EmbeddedType = embeddedType; }