Example #1
0
        private GenericTypeLookupGraph BuildGenericTypeResolutionGraph(EntityModelSchema model)
        {
            var graph = new GenericTypeLookupGraph();

            foreach (var unmappedBaseType in model.EntityTypes.Where(e => (e.Annotations.OfType <ObjectLayerOnlyAnnotation>().Any() || e.Annotations.OfType <GenericTypeAnnotation>().Any()) && e.BaseType == null))
            {
                var genericTypeAnnotation = unmappedBaseType.Annotations.OfType <GenericTypeAnnotation>().FirstOrDefault();
                if (genericTypeAnnotation == null)
                {
                    continue;
                }

                int count = genericTypeAnnotation.TypeParameters.Count;
                for (int i = 0; i < count; ++i)
                {
                    var lookups           = new Dictionary <EntityType, GenericArgument>();
                    var typeParameterName = genericTypeAnnotation.TypeParameters[i];
                    graph.Add(new GenericTypeParameter(unmappedBaseType, typeParameterName), lookups);

                    this.WalkChildren(graph, model, unmappedBaseType, typeParameterName, lookups);
                }
            }

            return(graph);
        }
Example #2
0
        private void WalkChildren(GenericTypeLookupGraph graph, EntityModelSchema model, EntityType baseType, string typeParameterName, Dictionary <EntityType, GenericArgument> lookups)
        {
            foreach (var childType in model.EntityTypes.Where(e => e.BaseType == baseType))
            {
                var genericTypeAnnotation      = childType.Annotations.OfType <GenericTypeAnnotation>().FirstOrDefault();
                var genericArgumentsAnnotation = childType.Annotations.OfType <GenericArgumentsAnnotation>().FirstOrDefault();

                GenericArgument argument        = null;
                bool            argumentMissing = genericArgumentsAnnotation == null ||
                                                  (argument = genericArgumentsAnnotation.GenericArguments.SingleOrDefault(ga => ga.TypeParameterName == typeParameterName)) == null;
                if (argumentMissing)
                {
                    var exception = new TaupoArgumentException(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Entity type {0} cannot derive from entity type {1} because {0} does not have a type parameter {2} specified by a {3}.",
                            childType.Name,
                            baseType.Name,
                            typeParameterName,
                            typeof(GenericTypeAnnotation).Name));

                    if (genericTypeAnnotation == null)
                    {
                        throw exception;
                    }

                    var childTypeParameterPosition = genericTypeAnnotation.TypeParameters.IndexOf(typeParameterName);

                    if (childTypeParameterPosition == -1)
                    {
                        throw exception;
                    }

                    var childLookups = new Dictionary <EntityType, GenericArgument>();
                    graph.Add(new GenericTypeParameter(childType, typeParameterName), childLookups);

                    this.WalkChildren(graph, model, childType, typeParameterName, childLookups);

                    // Merge the child lookups back into lookups
                    foreach (var kvp in childLookups)
                    {
                        lookups[kvp.Key] = kvp.Value;
                    }
                }
                else
                {
                    lookups[childType] = argument;
                }
            }
        }