Esempio n. 1
0
            public override object ConvertFrom(ref ObjectContext context, Scalar fromScalar)
            {
                Guid identifier;

                if (!TryParse(fromScalar.Value, out identifier))
                {
                    throw new YamlException($"Unable to deserialize reference: [{fromScalar.Value}]");
                }

                // Add the path to the currently deserialized object to the list of object references
                YamlAssetMetadata <Guid> objectReferences;

                if (!context.SerializerContext.Properties.TryGetValue(AssetObjectSerializerBackend.ObjectReferencesKey, out objectReferences))
                {
                    objectReferences = new YamlAssetMetadata <Guid>();
                    context.SerializerContext.Properties.Add(AssetObjectSerializerBackend.ObjectReferencesKey, objectReferences);
                }
                var path = AssetObjectSerializerBackend.GetCurrentPath(ref context, true);

                objectReferences.Set(path, identifier);

                // Return default(T)
                //return !context.Descriptor.Type.IsValueType ? null : Activator.CreateInstance(context.Descriptor.Type);
                // Return temporary proxy instance
                var proxy = (IIdentifiable)AbstractObjectInstantiator.CreateConcreteInstance(context.Descriptor.Type);

                proxy.Id = identifier;
                return(proxy);
            }
Esempio n. 2
0
        public void TestInterfaceImplementationInstantiation()
        {
            var instance = AbstractObjectInstantiator.CreateConcreteInstance(typeof(InterfaceImpl));

            // Check the type
            Assert.NotEqual(typeof(InterfaceImpl), instance.GetType());
            Assert.NotEqual(typeof(IInterface), instance.GetType());
            // Check the base type
            Assert.IsAssignableFrom <InterfaceImpl>(instance);
            // Check the base interface
            Assert.IsAssignableFrom <IInterface>(instance);

            // Check read access to 'A' property
            { var a = ((InterfaceImpl)instance).A; }
            // Check write access to 'A' property
            { ((InterfaceImpl)instance).A = null; }
            // Check read access to 'B' property
            { var b = ((IInterface)instance).B; }
            // Check write access to 'B' property
            { ((IInterface)instance).B = null; }

            // Check call to 'MethodA'
            { ((InterfaceImpl)instance).MethodA(); }
            // Check call to 'MethodB'
            { ((IInterface)instance).MethodB(); }
        }
Esempio n. 3
0
        public void TestInterfaceInstantiation()
        {
            var instance = AbstractObjectInstantiator.CreateConcreteInstance(typeof(IInterface));

            // Check the type
            Assert.NotEqual(typeof(IInterface), instance.GetType());
            // Check the base type
            Assert.IsAssignableFrom <IInterface>(instance);

            // Check read access to 'A' property
            Assert.Throws <NotImplementedException>(() => { var a = ((IInterface)instance).A; });
            // Check write access to 'A' property
            Assert.Throws <NotImplementedException>(() => { ((IInterface)instance).A = null; });
            // Check read access to 'B' property
            Assert.Throws <NotImplementedException>(() => { var b = ((IInterface)instance).B; });
            // Check write access to 'B' property
            Assert.Throws <NotImplementedException>(() => { ((IInterface)instance).B = null; });

            // Check call to 'MethodA'
            Assert.Throws <NotImplementedException>(() => { ((IInterface)instance).MethodA(); });
            // Check call to 'MethodB'
            Assert.Throws <NotImplementedException>(() => { ((IInterface)instance).MethodB(); });
        }
Esempio n. 4
0
        public void TestAbstractClassInstantiation()
        {
            var instance = AbstractObjectInstantiator.CreateConcreteInstance(typeof(AbstractClass));

            // Check the type
            Assert.AreNotEqual(typeof(AbstractClass), instance.GetType());
            // Check the base type
            Assert.IsInstanceOf <AbstractClass>(instance);

            // Check read access to 'A' property
            Assert.DoesNotThrow(() => { var a = ((AbstractClass)instance).A; });
            // Check write access to 'A' property
            Assert.DoesNotThrow(() => { ((AbstractClass)instance).A = null; });
            // Check read access to 'B' property
            Assert.Throws <NotImplementedException>(() => { var b = ((AbstractClass)instance).B; });
            // Check write access to 'B' property
            Assert.Throws <NotImplementedException>(() => { ((AbstractClass)instance).B = null; });

            // Check call to 'MethodA'
            Assert.DoesNotThrow(() => { ((AbstractClass)instance).MethodA(); });
            // Check call to 'MethodB'
            Assert.Throws <NotImplementedException>(() => { ((AbstractClass)instance).MethodB(); });
        }
Esempio n. 5
0
        /// <summary>
        /// Creates an object that implements the given <paramref name="baseType"/> and <see cref="IUnloadable"/>.
        /// </summary>
        /// <param name="baseType"></param>
        /// <param name="typeName"></param>
        /// <param name="parsingEvents"></param>
        /// <returns></returns>
        public static IUnloadable CreateUnloadableObject(Type baseType, string typeName, string assemblyName, string error, List <ParsingEvent> parsingEvents)
        {
            Type proxyType;

            lock (proxyTypes)
            {
                if (!proxyTypes.TryGetValue(baseType, out proxyType))
                {
                    var asmName = new AssemblyName($"YamlProxy_{Guid.NewGuid():N}");

                    // Create assembly (in memory)
                    var asmBuilder    = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
                    var moduleBuilder = asmBuilder.DefineDynamicModule("DynamicModule");

                    // Create type
                    var typeBuilder = moduleBuilder.DefineType($"{baseType}YamlProxy");
                    AbstractObjectInstantiator.InitializeTypeBuilderFromType(typeBuilder, baseType);

                    // Add DisplayAttribute
                    var displayAttributeCtor = typeof(DisplayAttribute).GetConstructor(new Type[] { typeof(string), typeof(string) });
                    var displayAttribute     = new CustomAttributeBuilder(displayAttributeCtor, new object[] { "Error: unable to load this object", null });
                    typeBuilder.SetCustomAttribute(displayAttribute);

                    // Add NonInstantiableAttribute
                    var nonInstantiableAttributeCtor = typeof(NonInstantiableAttribute).GetConstructor(Type.EmptyTypes);
                    var nonInstantiableAttribute     = new CustomAttributeBuilder(nonInstantiableAttributeCtor, new object[0]);
                    typeBuilder.SetCustomAttribute(nonInstantiableAttribute);

                    // Implement IUnloadable
                    typeBuilder.AddInterfaceImplementation(typeof(IUnloadable));

                    var backingFields = new List <FieldBuilder>();
                    foreach (var property in new[] { new { Name = nameof(IUnloadable.TypeName), Type = typeof(string) }, new { Name = nameof(IUnloadable.AssemblyName), Type = typeof(string) }, new { Name = nameof(IUnloadable.Error), Type = typeof(string) }, new { Name = nameof(IUnloadable.ParsingEvents), Type = typeof(List <ParsingEvent>) } })
                    {
                        // Add backing field
                        var backingField = typeBuilder.DefineField($"{property.Name.ToLowerInvariant()}", property.Type, FieldAttributes.Private);
                        backingFields.Add(backingField);

                        // Create property
                        var propertyBuilder = typeBuilder.DefineProperty(property.Name, PropertyAttributes.HasDefault, property.Type, Type.EmptyTypes);

                        // Create getter method
                        var propertyGetter = typeBuilder.DefineMethod($"get_{property.Name}",
                                                                      MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, property.Type, Type.EmptyTypes);
                        var propertyGetterIL = propertyGetter.GetILGenerator();
                        propertyGetterIL.Emit(OpCodes.Ldarg_0);
                        propertyGetterIL.Emit(OpCodes.Ldfld, backingField);
                        propertyGetterIL.Emit(OpCodes.Ret);
                        propertyBuilder.SetGetMethod(propertyGetter);

                        // Add DataMemberIgnoreAttribute
                        var dataMemberIgnoreAttributeCtor = typeof(DataMemberIgnoreAttribute).GetConstructor(Type.EmptyTypes);
                        var dataMemberIgnoreAttribute     = new CustomAttributeBuilder(dataMemberIgnoreAttributeCtor, new object[0]);
                        propertyBuilder.SetCustomAttribute(dataMemberIgnoreAttribute);
                    }

                    // .ctor (initialize backing fields too)
                    var ctor   = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, backingFields.Select(x => x.FieldType).ToArray());
                    var ctorIL = ctor.GetILGenerator();
                    // Call parent ctor (if one without parameters exist)
                    var defaultCtor = baseType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
                    if (defaultCtor != null)
                    {
                        ctorIL.Emit(OpCodes.Ldarg_0);
                        ctorIL.Emit(OpCodes.Call, defaultCtor);
                    }
                    // Initialize fields
                    for (var index = 0; index < backingFields.Count; index++)
                    {
                        var backingField = backingFields[index];
                        ctorIL.Emit(OpCodes.Ldarg_0);
                        ctorIL.Emit(OpCodes.Ldarg, index + 1);
                        ctorIL.Emit(OpCodes.Stfld, backingField);
                    }
                    ctorIL.Emit(OpCodes.Ret);

                    // User-registered callbacks
                    ProcessProxyType?.Invoke(baseType, typeBuilder);

                    proxyType = typeBuilder.CreateType();
                    proxyTypes.Add(baseType, proxyType);
                }
            }

            return((IUnloadable)Activator.CreateInstance(proxyType, typeName, assemblyName, error, parsingEvents));
        }