private static SourceAndDestinationTypes SourceAndDestinationTypesSelector(TypeExtensions.ConcreteTypeAndInterface concreteTypeAndInterfaces, Boolean swapDestinationAndSourceTypes = false)
 {
     if (swapDestinationAndSourceTypes)
     {
         return new SourceAndDestinationTypes(concreteTypeAndInterfaces.ConcreteType,
                                              concreteTypeAndInterfaces.InterfaceType.GetGenericArguments()[0]);
     }
     return new SourceAndDestinationTypes(concreteTypeAndInterfaces.InterfaceType.GetGenericArguments()[0],concreteTypeAndInterfaces.ConcreteType);
 }
Пример #2
0
        private void WriteClassChild(CodeWriter writer, Association child, bool hasDuplicates, Database schema, GenerationContext context)
        {
            // the following is apparently useless
            DbLinq.Schema.Dbml.Table targetTable = schema.Tables.FirstOrDefault(t => t.Type.Name == child.Type);
            if (targetTable == null)
            {
                //Logger.Write(Level.Error, "ERROR L143 target table class not found:" + child.Type);
                return;
            }

            var storageAttribute = NewAttributeDefinition <AssociationAttribute>();

            storageAttribute["Storage"]  = child.Storage;
            storageAttribute["OtherKey"] = child.OtherKey;
            storageAttribute["ThisKey"]  = child.ThisKey;
            storageAttribute["Name"]     = child.Name;

            SpecificationDefinition specifications;

            if (child.AccessModifierSpecified)
            {
                specifications = GetSpecificationDefinition(child.AccessModifier);
            }
            else
            {
                specifications = SpecificationDefinition.Public;
            }
            if (child.ModifierSpecified)
            {
                specifications |= GetSpecificationDefinition(child.Modifier);
            }

            var propertyName = hasDuplicates
                                   ? child.Member + "_" + string.Join("", child.OtherKeys.ToArray())
                                   : child.Member;

            var propertyType = writer.GetGenericName(TypeExtensions.GetShortName(typeof(EntitySet <>)), child.Type);

            if (child.Storage != null)
            {
                writer.WriteField(SpecificationDefinition.Private, child.Storage, propertyType);
            }

            using (writer.WriteAttribute(storageAttribute))
                using (writer.WriteAttribute(NewAttributeDefinition <DebuggerNonUserCodeAttribute>()))
                    using (writer.WriteProperty(specifications, propertyName,
                                                writer.GetGenericName(TypeExtensions.GetShortName(typeof(EntitySet <>)), child.Type)))
                    {
                        // if we have a backing field, use it
                        if (child.Storage != null)
                        {
                            // the getter returns the field
                            using (writer.WritePropertyGet())
                            {
                                writer.WriteLine(writer.GetReturnStatement(
                                                     child.Storage
                                                     ));
                            }
                            // the setter assigns the field
                            using (writer.WritePropertySet())
                            {
                                writer.WriteLine(writer.GetStatement(
                                                     writer.GetAssignmentExpression(
                                                         child.Storage,
                                                         writer.GetPropertySetValueExpression())
                                                     ));
                            }
                        }
                        // otherwise, use automatic property
                        else
                        {
                            writer.WriteAutomaticPropertyGetSet();
                        }
                    }
            writer.WriteLine();
        }
Пример #3
0
        protected virtual bool PrepareMember(MemberDescriptorBase member)
        {
            var memberType = member.Type;

            // Remove all SyncRoot from members
            if (member is PropertyDescriptor && member.OriginalName == "SyncRoot" &&
                (member.DeclaringType.Namespace ?? string.Empty).StartsWith(SystemCollectionsNamespace))
            {
                return(false);
            }

            // Process all attributes just once instead of getting them one by one
            var attributes = AttributeRegistry.GetAttributes(member.MemberInfo);
            YamlStyleAttribute    styleAttribute        = null;
            YamlMemberAttribute   memberAttribute       = null;
            DefaultValueAttribute defaultValueAttribute = null;

            foreach (var attribute in attributes)
            {
                // Member is not displayed if there is a YamlIgnore attribute on it
                if (attribute is YamlIgnoreAttribute)
                {
                    return(false);
                }

                if (attribute is YamlMemberAttribute)
                {
                    memberAttribute = (YamlMemberAttribute)attribute;
                    continue;
                }

                if (attribute is DefaultValueAttribute)
                {
                    defaultValueAttribute = (DefaultValueAttribute)attribute;
                    continue;
                }

                if (attribute is YamlStyleAttribute)
                {
                    styleAttribute = (YamlStyleAttribute)attribute;
                    continue;
                }

                var yamlRemap = attribute as YamlRemapAttribute;
                if (yamlRemap != null)
                {
                    if (member.AlternativeNames == null)
                    {
                        member.AlternativeNames = new List <string>();
                    }
                    if (!string.IsNullOrWhiteSpace(yamlRemap.Name))
                    {
                        member.AlternativeNames.Add(yamlRemap.Name);
                    }
                }
            }

            // If the member has a set, this is a conventional assign method
            if (member.HasSet)
            {
                member.SerializeMemberMode = SerializeMemberMode.Content;
            }
            else
            {
                // Else we cannot only assign its content if it is a class
                member.SerializeMemberMode = (memberType != typeof(string) && memberType.IsClass) || memberType.IsInterface || type.IsAnonymous() ? SerializeMemberMode.Content : SerializeMemberMode.Never;
            }

            // If it's a private member, check it has a YamlMemberAttribute on it
            if (!member.IsPublic)
            {
                if (memberAttribute == null)
                {
                    return(false);
                }
            }

            // Gets the style
            member.Style = styleAttribute != null ? styleAttribute.Style : YamlStyle.Any;
            member.Mask  = 1;

            // Handle member attribute
            if (memberAttribute != null)
            {
                member.Mask = memberAttribute.Mask;
                if (!member.HasSet)
                {
                    if (memberAttribute.SerializeMethod == SerializeMemberMode.Assign ||
                        (memberType.IsValueType && member.SerializeMemberMode == SerializeMemberMode.Content))
                    {
                        throw new ArgumentException("{0} {1} is not writeable by {2}.".DoFormat(memberType.FullName, member.OriginalName, memberAttribute.SerializeMethod.ToString()));
                    }
                }

                if (memberAttribute.SerializeMethod != SerializeMemberMode.Default)
                {
                    member.SerializeMemberMode = memberAttribute.SerializeMethod;
                }
                member.Order = memberAttribute.Order;
            }

            if (member.SerializeMemberMode == SerializeMemberMode.Binary)
            {
                if (!memberType.IsArray)
                {
                    throw new InvalidOperationException("{0} {1} of {2} is not an array. Can not be serialized as binary."
                                                        .DoFormat(memberType.FullName, member.OriginalName, type.FullName));
                }
                if (!memberType.GetElementType().IsPureValueType())
                {
                    throw new InvalidOperationException("{0} is not a pure ValueType. {1} {2} of {3} can not serialize as binary.".DoFormat(memberType.GetElementType(), memberType.FullName, member.OriginalName, type.FullName));
                }
            }

            // If this member cannot be serialized, remove it from the list
            if (member.SerializeMemberMode == SerializeMemberMode.Never)
            {
                return(false);
            }

            // ShouldSerialize
            //	  YamlSerializeAttribute(Never) => false
            //	  ShouldSerializeSomeProperty => call it
            //	  DefaultValueAttribute(default) => compare to it
            //	  otherwise => true
            var shouldSerialize = type.GetMethod("ShouldSerialize" + member.OriginalName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            if (shouldSerialize != null && shouldSerialize.ReturnType == typeof(bool) && member.ShouldSerialize == null)
            {
                member.ShouldSerialize = obj => (bool)shouldSerialize.Invoke(obj, EmptyObjectArray);
            }

            if (defaultValueAttribute != null && member.ShouldSerialize == null && !emitDefaultValues)
            {
                object defaultValue = defaultValueAttribute.Value;
                Type   defaultType  = defaultValue == null ? null : defaultValue.GetType();
                if (defaultType.IsNumeric() && defaultType != memberType)
                {
                    defaultValue = memberType.CastToNumericType(defaultValue);
                }
                member.ShouldSerialize = obj => !TypeExtensions.AreEqual(defaultValue, member.Get(obj));
            }

            if (member.ShouldSerialize == null)
            {
                member.ShouldSerialize = ShouldSerializeDefault;
            }

            if (memberAttribute != null && !string.IsNullOrEmpty(memberAttribute.Name))
            {
                member.Name = memberAttribute.Name;
            }
            else
            {
                member.Name = NamingConvention.Convert(member.OriginalName);
            }

            return(true);
        }
 public void DerivedTypeFromBaseType()
 {
     Assert.That(TypeExtensions.GetAscribedGenericArguments(typeof(DerivedType), typeof(BaseType)), Is.EqualTo(new Type[0]));
 }
        public void TypeOf_IsNullable_Object_Test()
        {
            var value = TypeExtensions.IsNullable <object>();

            Assert.IsFalse(value);
        }
        public void TypeOf_IsNullable_ListOfT_Test()
        {
            var value = TypeExtensions.IsNullable <List <object> >();

            Assert.IsFalse(value);
        }
Пример #7
0
        private static void HandleTypeGetMethod(ref DependencyList list, NodeFactory factory, TypeDesc type, string name, string reason)
        {
            if (factory.MetadataManager.IsReflectionBlocked(type))
            {
                return;
            }

            if (type.IsGenericDefinition)
            {
                Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(type.Instantiation, allowCanon: false);
                if (inst.IsNull)
                {
                    return;
                }
                type = ((MetadataType)type).MakeInstantiatedType(inst);
                list = list ?? new DependencyList();
                list.Add(factory.MaximallyConstructableType(type), reason);
            }
            else
            {
                // Type could be something weird like SomeType<object, __Canon> - normalize it
                type = type.NormalizeInstantiation();
            }

            MethodDesc reflectedMethod = type.GetMethod(name, null);

            if (reflectedMethod != null &&
                !factory.MetadataManager.IsReflectionBlocked(reflectedMethod))
            {
                if (reflectedMethod.HasInstantiation)
                {
                    // Don't want to accidentally get Foo<__Canon>.Bar<object>()
                    if (reflectedMethod.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))
                    {
                        return;
                    }

                    Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(reflectedMethod.Instantiation, allowCanon: false);
                    if (inst.IsNull)
                    {
                        return;
                    }
                    reflectedMethod = reflectedMethod.MakeInstantiatedMethod(inst);
                }

                list = list ?? new DependencyList();
                if (reflectedMethod.IsVirtual)
                {
                    RootVirtualMethodForReflection(ref list, factory, reflectedMethod, reason);
                }

                if (!reflectedMethod.IsAbstract)
                {
                    list.Add(factory.CanonicalEntrypoint(reflectedMethod), reason);
                    if (reflectedMethod.HasInstantiation &&
                        reflectedMethod != reflectedMethod.GetCanonMethodTarget(CanonicalFormKind.Specific))
                    {
                        list.Add(factory.MethodGenericDictionary(reflectedMethod), reason);
                    }
                }
            }
        }
 static EquatableStructAtomHandler()
 {
     Comparer = TypeExtensions.GetEqualityComparerDelegate <T>();
 }
Пример #9
0
        public void Invoke_StringArgument_ReturnsString()
        {
            MethodInfo method = TypeExtensions.GetMethod(typeof(MI_NonGenericClass), nameof(MI_NonGenericClass.MethodA), new Type[] { typeof(string) });

            Assert.Equal("test string", method.Invoke(new MI_NonGenericClass(), new object[] { "test string" }));
        }
Пример #10
0
        /// <summary>
        /// Applies the specified source.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="filterValue">The filter value.</param>
        /// <param name="context">The context.</param>
        /// <returns>IQueryable&lt;T&gt;.</returns>
        public IQueryable <T> Apply(IQueryable <T> source, object filterValue, IContext context)
        {
            TFilterValue filterVal = TypeExtensions.ParseToTypedObject <TFilterValue>(filterValue);

            return(this.ApplyFilter(source, filterVal, context));
        }
Пример #11
0
 public static IGeneratorDef Foreign <TEntity>(Expression <Func <TEntity, object> > property)
 {
     return(new ForeignGeneratorDef(TypeExtensions.DecodeMemberAccessExpression(property)));
 }
Пример #12
0
        public void OrderBy <TProperty>(Expression <Func <TElement, TProperty> > property)
        {
            var member = TypeExtensions.DecodeMemberAccessExpression(property);

            CustomizersHolder.AddCustomizer(PropertyPath, (ICollectionPropertiesMapper x) => x.OrderBy(member));
        }
Пример #13
0
 public void IsGenericAssignableFrom_Should_Check_If_Type_IsAssignableFrom(Type input, Type other, bool expect)
 {
     Console.WriteLine("Checking if type {0} isassignablefrom {1} (expecting {2})", input, other, expect);
     Assert.Equal(expect, TypeExtensions.IsGenericAssignableFrom(input, other));
 }
Пример #14
0
 public void IsGenericAssignableFrom_Should_Throw_If_Other_Argument_Null()
 {
     Assert.Throws <ArgumentNullException>(() => TypeExtensions.IsGenericAssignableFrom(typeof(IGenericInterface <>), null));
 }
Пример #15
0
 public void IsGenericAssignableFrom_Should_Throw_If_Argument_Null()
 {
     Assert.Throws <ArgumentNullException>(() => TypeExtensions.IsGenericAssignableFrom(null, typeof(object)));
 }
Пример #16
0
 public virtual bool IsOfKind <T>()
 {
     return(TypeExtensions.IsOfKind <T>(this) || ExtendedWith().Contains(typeof(T)));
 }
Пример #17
0
        private void InternalSerializeInstance(BinaryWriter writer, object o)
        {
            Type t = o.GetType();

            switch (TypeExtensions.GetTypeCode(t))
            {
            case TypeCode.Boolean: writer.Write((bool)o); break;

            case TypeCode.Char: writer.Write((char)o); break;

            case TypeCode.SByte: writer.Write((sbyte)o); break;

            case TypeCode.Byte: writer.Write((byte)o); break;

            case TypeCode.Int16: writer.Write((short)o); break;

            case TypeCode.UInt16: writer.Write((ushort)o); break;

            case TypeCode.Int32: writer.Write((int)o); break;

            case TypeCode.UInt32: writer.Write((uint)o); break;

            case TypeCode.Int64: writer.Write((long)o); break;

            case TypeCode.UInt64: writer.Write((ulong)o); break;

            case TypeCode.Single:
                if (Capabilities.FloatingPoint)
                {
                    writer.Write((float)o);
                }
                else
                {
                    writer.Write((int)((float)o * 1024));
                }
                break;

            case TypeCode.Double:
                if (Capabilities.FloatingPoint)
                {
                    writer.Write((double)o);
                }
                else
                {
                    writer.Write((long)((double)o * 65536));
                }
                break;

            case TypeCode.String:
                byte[] buf = Encoding.UTF8.GetBytes((string)o);

                writer.Write(buf.Length);
                writer.Write(buf);
                break;

            default:
                if (t == typeof(void))
                {
                }
                else if (t.IsArray)
                {
                    Array arr = (Array)o;

                    foreach (object arrItem in arr)
                    {
                        InternalSerializeInstance(writer, arrItem);
                    }
                }
                else if (t.GetRuntimeProperties().FirstOrDefault(n => n.Name == "Count") != null)
                {
                    // type implements Count property so it's a list

                    // cast to IList
                    IList list = (IList)o;

                    // go through each list item and serialize it
                    foreach (object arrItem in list)
                    {
                        InternalSerializeInstance(writer, arrItem);
                    }
                }
                else if (t.GetTypeInfo().IsValueType || t.GetTypeInfo().IsClass)
                {
                    InternalSerializeFields(writer, o);
                }
                else
                {
                    throw new SerializationException();
                }

                break;
            }
        }
Пример #18
0
 public string BuildTypeName(IType target, bool shortFormGeneric = false, bool numericTypeParams = false, TypeParameterDisplayMode typeParameterDisplayMode = TypeParameterDisplayMode.SystemStandard)
 {
     callcount++;
     return(TypeExtensions.BuildTypeNameInternal(target, shortFormGeneric, numericTypeParams, typeParameterDisplayMode));
 }
Пример #19
0
        private object InternalDeserializeInstance(BinaryReader reader, object o, Type t)
        {
            object ret = null;

            if (o != null)
            {
                //This allows PrepareForDeserialize to subclass the expected type if appropriate
                t = o.GetType();

                //Debug.WriteLine("Deserializing instance " + t.Name);
            }

            switch (TypeExtensions.GetTypeCode(t))
            {
            case TypeCode.Boolean: ret = reader.ReadBoolean(); break;

            case TypeCode.Char: ret = reader.ReadChar(); break;

            case TypeCode.SByte: ret = reader.ReadSByte(); break;

            case TypeCode.Byte: ret = reader.ReadByte(); break;

            case TypeCode.Int16: ret = reader.ReadInt16(); break;

            case TypeCode.UInt16: ret = reader.ReadUInt16(); break;

            case TypeCode.Int32: ret = reader.ReadInt32(); break;

            case TypeCode.UInt32: ret = reader.ReadUInt32(); break;

            case TypeCode.Int64: ret = reader.ReadInt64(); break;

            case TypeCode.UInt64: ret = reader.ReadUInt64(); break;

            case TypeCode.Single:
                if (Capabilities.FloatingPoint)
                {
                    ret = reader.ReadSingle();
                }
                else
                {
                    ret = (float)reader.ReadInt32() / 1024;
                }
                break;

            case TypeCode.Double:
                if (Capabilities.FloatingPoint)
                {
                    ret = reader.ReadDouble();
                }
                else
                {
                    ret = (double)reader.ReadInt64() / 65536;
                }
                break;

            case TypeCode.String:
                int    num = reader.ReadInt32();
                byte[] buf = reader.ReadBytes(num);

                ret = Encoding.UTF8.GetString(buf, 0, num);

                break;

            default:
                if (t.IsArray)
                {
                    Array arr = (Array)o;

                    for (int i = 0; i < arr.Length; i++)
                    {
                        object objValue = arr.GetValue(i);

                        //if(reader.BaseStream.Position >= reader.BaseStream.Length)
                        //{
                        //    Debug.WriteLine("######################################################");
                        //    Debug.WriteLine("################ trying to read after end of stream ");
                        //}

                        objValue = InternalDeserializeInstance(reader, objValue, t.GetElementType());
                        arr.SetValue(objValue, i);
                    }

                    ret = o;
                }
                else if (t.GetRuntimeProperties().FirstOrDefault(n => n.Name == "Count") != null)
                {
                    // type implements Count property so it's a list

                    // cast to IList
                    IList list = (IList)o;

                    // go through each list item and deserialize it
                    for (int i = 0; i < list.Count; i++)
                    {
                        list[i] = InternalDeserializeInstance(reader, list[i], list[i].GetType());
                    }

                    // done here, return the de-serialized list
                    ret = list;
                }
                else if (t.GetTypeInfo().IsValueType || t.GetTypeInfo().IsClass)
                {
                    if (o != null)
                    {
                        if (o.GetType() != t)
                        {
                            throw new System.Runtime.Serialization.SerializationException();
                        }
                    }
                    else
                    {
                        o = Activator.CreateInstance(t);
                    }

                    InternalDeserializeFields(reader, o);

                    ret = o;
                }
                else
                {
                    throw new System.Runtime.Serialization.SerializationException();
                }

                break;
            }

            return(ret);
        }
Пример #20
0
 /// <inheritdoc />
 protected override string GetPopupItemLabel(Type value)
 {
     return(TypeExtensions.GetPopupMenuLabel(value));
 }
Пример #21
0
        public void GetGenericInterface_ArgumentIsNull_ArgumentNullException()
        {
            Action act = () => TypeExtensions.GetGenericInterface(null, typeof(ISomeInterface));

            act.ShouldThrow <ArgumentNullException>();
        }
        public void TypeOf_IsNullable_MyType_Test()
        {
            var value = TypeExtensions.IsNullable <MyType>();

            Assert.IsFalse(value);
        }
Пример #23
0
        public void PrimitiveCollection()
        {
            var excludeTypes = new TypeCode[]
            {
                TypeCode.Empty,
                TypeCode.DBNull,
                TypeCode.DateTime, //DateTime is not managed
                TypeCode.Object,
                TypeCode.Boolean,  //Bool flattens value to 0 or 1 so hashset differ too much. change the verifier to take care of conversions
            };

            var types = Enum.GetValues(typeof(TypeCode)).Cast <TypeCode>()
                        .Except(excludeTypes)
                        .Select(typeCode => TypeExtensions.GetType(typeCode)).ToList();

            foreach (var sourceElementType in types)
            {
                foreach (var targetElementType in types)
                {
                    //for the following pairs a conversion is known
                    //to be harder (not possible or convention-based),
                    //so here we just skip that few cases

                    if (sourceElementType == typeof(string) &&
                        targetElementType == typeof(bool))
                    {
                        continue;
                    }

                    if (sourceElementType == typeof(char) &&
                        targetElementType == typeof(bool))
                    {
                        continue;
                    }

                    if (sourceElementType == typeof(bool) &&
                        targetElementType == typeof(char))
                    {
                        continue;
                    }


                    var sourceType = typeof(GenericCollections <>)
                                     .MakeGenericType(sourceElementType);

                    var targetType = typeof(GenericCollections <>)
                                     .MakeGenericType(targetElementType);

                    var sourceTypeCtor = ConstructorFactory.CreateConstructor <bool, uint, uint>(sourceType);
                    var targetTypeCtor = ConstructorFactory.CreateConstructor <bool, uint, uint>(targetType);

                    var source = sourceTypeCtor(true, 0, 10);
                    var target = targetTypeCtor(false, 0, 10);

                    var ultraMapper = new Mapper();
                    ultraMapper.Map(source, target);

                    bool isResultOk = ultraMapper.VerifyMapperResult(source, target);
                    Assert.IsTrue(isResultOk);
                }
            }
        }
        public void TypeOf_IsNullable2_NullableInt_Test()
        {
            var value = TypeExtensions.IsNullable <int?>();

            Assert.IsTrue(value);
        }
Пример #25
0
        public void Parent <TProperty>(Expression <Func <TComponent, TProperty> > parent, Action <IComponentParentMapper> parentMapping) where TProperty : class
        {
            MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(parent);

            AddCustomizer(m => m.Parent(member, parentMapping));
        }
 public void BaseType()
 {
     TypeExtensions.GetAscribedGenericArguments(typeof(BaseType), typeof(DerivedType));
 }
Пример #27
0
        private T GetQueryValue <T>(string key, T defaultValue)
        {
            var stringValue = GetQueryStringValue(key);

            return(!string.IsNullOrEmpty(stringValue) ? (T)TypeExtensions.ChangeType(stringValue, typeof(T)) : defaultValue);
        }
Пример #28
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            string s = reader.Value as string;

            return(TypeExtensions.GetType(s));
        }
Пример #29
0
 public void WhenDecodeMemberAccessExpressionOfOnInheritedEntityInterfaceThenDecodeMember()
 {
     Assert.That(TypeExtensions.DecodeMemberAccessExpressionOf <IMyEntity>(m => m.Id), Is.Not.Null);
     Assert.That(TypeExtensions.DecodeMemberAccessExpressionOf <IMyEntity, Guid>(m => m.Id), Is.Not.Null);
 }
Пример #30
0
        protected virtual void WriteClassParent(CodeWriter writer, Association parent, bool hasDuplicates, Database schema, GenerationContext context)
        {
            // the following is apparently useless
            DbLinq.Schema.Dbml.Table targetTable = schema.Tables.FirstOrDefault(t => t.Type.Name == parent.Type);
            if (targetTable == null)
            {
                //Logger.Write(Level.Error, "ERROR L191 target table type not found: " + parent.Type + "  (processing " + parent.Name + ")");
                return;
            }

            string member       = parent.Member;
            string storageField = parent.Storage;

            // TODO: remove this
            if (member == parent.ThisKey)
            {
                member       = parent.ThisKey + targetTable.Type.Name; //repeat name to prevent collision (same as Linq)
                storageField = "_x_" + parent.Member;
            }

            writer.WriteField(SpecificationDefinition.Private, storageField,
                              writer.GetGenericName(TypeExtensions.GetShortName(typeof(EntityRef <>)),
                                                    targetTable.Type.Name));

            var storageAttribute = NewAttributeDefinition <AssociationAttribute>();

            storageAttribute["Storage"]      = storageField;
            storageAttribute["OtherKey"]     = parent.OtherKey;
            storageAttribute["ThisKey"]      = parent.ThisKey;
            storageAttribute["Name"]         = parent.Name;
            storageAttribute["IsForeignKey"] = parent.IsForeignKey;

            SpecificationDefinition specifications;

            if (parent.AccessModifierSpecified)
            {
                specifications = GetSpecificationDefinition(parent.AccessModifier);
            }
            else
            {
                specifications = SpecificationDefinition.Public;
            }
            if (parent.ModifierSpecified)
            {
                specifications |= GetSpecificationDefinition(parent.Modifier);
            }

            var propertyName = hasDuplicates
                                   ? member + "_" + string.Join("", parent.TheseKeys.ToArray())
                                   : member;

            using (writer.WriteAttribute(storageAttribute))
                using (writer.WriteAttribute(NewAttributeDefinition <DebuggerNonUserCodeAttribute>()))
                    using (writer.WriteProperty(specifications, propertyName, targetTable.Type.Name))
                    {
                        string storage = writer.GetMemberExpression(storageField, "Entity");
                        using (writer.WritePropertyGet())
                        {
                            writer.WriteLine(writer.GetReturnStatement(storage));
                        }
                        using (writer.WritePropertySet())
                        {
                            // algorithm is:
                            // 1.1. must be different than previous value
                            // 1.2. or HasLoadedOrAssignedValue is false (but why?)
                            // 2. implementations before change
                            // 3. if previous value not null
                            // 3.1. place parent in temp variable
                            // 3.2. set [Storage].Entity to null
                            // 3.3. remove it from parent list
                            // 4. assign value to [Storage].Entity
                            // 5. if value is not null
                            // 5.1. add it to parent list
                            // 5.2. set FK members with entity keys
                            // 6. else
                            // 6.1. set FK members to defaults (null or 0)
                            // 7. implementationas after change

                            //writer.WriteLine(writer.GetStatement(writer.GetAssignmentExpression(storage, writer.GetPropertySetValueExpression())));
                            var entityMember = writer.GetMemberExpression(parent.Storage, "Entity");
                            // 1.1
                            using (writer.WriteIf(writer.GetDifferentExpression(writer.GetPropertySetValueExpression(),
                                                                                entityMember)))
                            {
                                var otherAssociation = schema.GetReverseAssociation(parent);
                                // 2. code before the change
                                // TODO change interface to require a member instead of a column
                                //foreach (IImplementation implementation in context.Implementations())
                                //    implementation.WritePropertyBeforeSet(writer, ???, context);
                                // 3.
                                using (writer.WriteIf(writer.GetDifferentExpression(entityMember, writer.GetNullExpression())))
                                {
                                    var previousEntityRefName = "previous" + parent.Type;
                                    // 3.1.
                                    writer.WriteLine(writer.GetStatement(
                                                         writer.GetVariableDeclarationInitialization(parent.Type, previousEntityRefName, entityMember)
                                                         ));
                                    // 3.2.
                                    writer.WriteLine(writer.GetStatement(
                                                         writer.GetAssignmentExpression(entityMember, writer.GetNullExpression())
                                                         ));
                                    // 3.3.
                                    writer.WriteLine(writer.GetStatement(
                                                         writer.GetMethodCallExpression(
                                                             writer.GetMemberExpression(writer.GetMemberExpression(previousEntityRefName, otherAssociation.Member), "Remove"),
                                                             writer.GetThisExpression())
                                                         ));
                                }
                                // 4.
                                writer.WriteLine(writer.GetStatement(
                                                     writer.GetAssignmentExpression(entityMember, writer.GetPropertySetValueExpression())
                                                     ));

                                // 5. if value is null or not
                                writer.WriteRawIf(writer.GetDifferentExpression(writer.GetPropertySetValueExpression(), writer.GetNullExpression()));
                                // 5.1.
                                writer.WriteLine(writer.GetStatement(
                                                     writer.GetMethodCallExpression(
                                                         writer.GetMemberExpression(writer.GetMemberExpression(writer.GetPropertySetValueExpression(), otherAssociation.Member), "Add"),
                                                         writer.GetThisExpression())
                                                     ));

                                // 5.2
                                var table        = schema.Tables.Single(t => t.Type.Associations.Contains(parent));
                                var childKeys    = parent.TheseKeys.ToArray();
                                var childColumns = (from ck in childKeys select table.Type.Columns.Single(c => c.Member == ck))
                                                   .ToArray();
                                var parentKeys = parent.OtherKeys.ToArray();

                                for (int keyIndex = 0; keyIndex < parentKeys.Length; keyIndex++)
                                {
                                    writer.WriteLine(writer.GetStatement(writer.GetAssignmentExpression(
                                                                             childColumns[keyIndex].Storage ?? childColumns[keyIndex].Member,
                                                                             writer.GetMemberExpression(writer.GetPropertySetValueExpression(), parentKeys[keyIndex])
                                                                             )));
                                }

                                // 6.
                                writer.WriteRawElse();

                                // 6.1.
                                for (int keyIndex = 0; keyIndex < parentKeys.Length; keyIndex++)
                                {
                                    var column            = table.Type.Columns.Single(c => c.Member == childKeys[keyIndex]);
                                    var columnType        = System.Type.GetType(column.Type);
                                    var columnLiteralType = columnType != null?writer.GetLiteralType(columnType) : column.Type;

                                    writer.WriteLine(writer.GetStatement(writer.GetAssignmentExpression(
                                                                             childColumns[keyIndex].Storage ?? childColumns[keyIndex].Member,
                                                                             column.CanBeNull ? writer.GetNullExpression() : writer.GetNullValueExpression(columnLiteralType)
                                                                             )));
                                }

                                writer.WriteRawEndif();

                                // 7. code after change
                                // TODO change interface to require a member instead of a column
                                //foreach (IImplementation implementation in context.Implementations())
                                //    implementation.WritePropertyAfterSet(writer, ???, context);
                            }
                        }
                    }
            writer.WriteLine();
        }
Пример #31
0
 public virtual bool IsOfType <T>()
 {
     return(TypeExtensions.IsOfType <T>(this));
 }