/// <summary>
        /// This method creates an instance of the <see cref="MetadataProvider"/>. Subclasses can override this
        /// method to provide their own construction logic.
        /// </summary>
        /// <param name="controllerType">The <see cref="DomainController"/> type to create a metadata provider for.</param>
        /// <param name="parent">The parent provider. May be null.</param>
        /// <returns>The metadata provider</returns>
        public virtual MetadataProvider CreateProvider(Type controllerType, MetadataProvider parent)
        {
            if (controllerType == null)
            {
                throw Error.ArgumentNull("controllerType");
            }

            if (!typeof(DomainController).IsAssignableFrom(controllerType))
            {
                throw Error.Argument("controllerType", Resource.InvalidType, controllerType.FullName, typeof(DomainController).FullName);
            }

            if (!typeof(MetadataProvider).IsAssignableFrom(_providerType))
            {
                throw Error.InvalidOperation(Resource.InvalidType, _providerType.FullName, typeof(MetadataProvider).FullName);
            }

            // Verify the type has a .ctor(MetadataProvider).
            if (_providerType.GetConstructor(new Type[] { typeof(MetadataProvider) }) == null)
            {
                throw Error.InvalidOperation(Resource.MetadataProviderAttribute_MissingConstructor, _providerType.FullName);
            }

            return (MetadataProvider)Activator.CreateInstance(_providerType, parent);
        }
        public DomainControllerTypeDescriptionProvider(Type type, MetadataProvider metadataProvider)
            : base(TypeDescriptor.GetProvider(type))
        {
            if (metadataProvider == null)
            {
                throw Error.ArgumentNull("metadataProvider");
            }

            _type = type;
            _metadataProvider = metadataProvider;
        }
        public LinqToEntitiesMetadataProvider(Type contextType, MetadataProvider parent, bool isDbContext)
            : base(parent)
        {
            _isDbContext = isDbContext;

            _typeDescriptionContext = _tdpContextMap.GetOrAdd(contextType, type =>
            {
                // create and cache a context for this provider type
                return new LinqToEntitiesTypeDescriptionContext(contextType, _isDbContext);
            });
        }
        /// <summary>
        /// This method creates an instance of the <see cref="MetadataProvider"/>.
        /// </summary>
        /// <param name="controllerType">The <see cref="DomainController"/> Type to create a metadata provider for.</param>
        /// <param name="parent">The existing parent metadata provider.</param>
        /// <returns>The metadata provider.</returns>
        public override MetadataProvider CreateProvider(Type controllerType, MetadataProvider parent)
        {
            if (controllerType == null)
            {
                throw Error.ArgumentNull("controllerType");
            }

            if (_objectContextType == null)
            {
                _objectContextType = GetContextType(controllerType);
            }

            if (!typeof(ObjectContext).IsAssignableFrom(_objectContextType))
            {
                throw Error.InvalidOperation(Resource.InvalidLinqToEntitiesMetadataProviderSpecification, _objectContextType);
            }

            return new LinqToEntitiesMetadataProvider(_objectContextType, parent, false);
        }
예제 #5
0
 /// <summary>
 /// Protected Constructor
 /// </summary>
 /// <param name="parent">The existing parent provider. May be null.</param>
 protected MetadataProvider(MetadataProvider parent)
 {
     _parentProvider = parent;
 }
 /// <summary>
 /// Protected Constructor
 /// </summary>
 /// <param name="parent">The existing parent provider. May be null.</param>
 protected MetadataProvider(MetadataProvider parent)
 {
     _parentProvider = parent;
 }
 /// <summary>
 /// Register our DomainControllerTypeDescriptionProvider for the specified Type. This provider is responsible for surfacing the
 /// custom TDs returned by metadata providers.
 /// </summary>
 /// <param name="type">The Type that we should register for.</param>
 /// <param name="metadataProvider">The metadata provider.</param>
 private static void RegisterDomainControllerTypeDescriptionProvider(Type type, MetadataProvider metadataProvider)
 {
     DomainControllerTypeDescriptionProvider tdp = new DomainControllerTypeDescriptionProvider(type, metadataProvider);
     RegisterCustomTypeDescriptor(tdp, type);
 }
        private static bool IsCustomUpdateMethod(MethodInfo method, MetadataProvider metadataProvider)
        {
            ParameterInfo[] parameters = method.GetParameters();
            if (parameters.Length == 0)
            {
                return false;
            }
            if (method.ReturnType != typeof(void))
            {
                return false;
            }

            return metadataProvider.IsEntityType(parameters[0].ParameterType);
        }
        private static ChangeOperation TryClassifyUpdateOperationImplicit(MethodInfo method, MetadataProvider metadataProvider)
        {
            ChangeOperation operationType = ChangeOperation.None;
            if (method.ReturnType == typeof(void))
            {
                // Check if this looks like an insert, update or delete method.
                if (_insertPrefixes.Any(p => method.Name.StartsWith(p, StringComparison.OrdinalIgnoreCase)))
                {
                    operationType = ChangeOperation.Insert;
                }
                else if (_updatePrefixes.Any(p => method.Name.StartsWith(p, StringComparison.OrdinalIgnoreCase)))
                {
                    operationType = ChangeOperation.Update;
                }
                else if (_deletePrefixes.Any(p => method.Name.StartsWith(p, StringComparison.OrdinalIgnoreCase)))
                {
                    operationType = ChangeOperation.Delete;
                }
                else if (IsCustomUpdateMethod(method, metadataProvider))
                {
                    operationType = ChangeOperation.Custom;
                }
            }

            return operationType;
        }
        private static ChangeOperation ClassifyUpdateOperation(MethodInfo method, MetadataProvider metadataProvider)
        {
            ChangeOperation operationType;

            AttributeCollection methodAttributes = new AttributeCollection(method.GetCustomAttributes(false).Cast<Attribute>().ToArray());

            // Check if explicit attributes exist.
            if (methodAttributes[typeof(InsertAttribute)] != null)
            {
                operationType = ChangeOperation.Insert;
            }
            else if (methodAttributes[typeof(UpdateAttribute)] != null)
            {
                UpdateAttribute updateAttribute = (UpdateAttribute)methodAttributes[typeof(UpdateAttribute)];
                if (updateAttribute.UsingCustomMethod)
                {
                    operationType = ChangeOperation.Custom;
                }
                else
                {
                    operationType = ChangeOperation.Update;
                }
            }
            else if (methodAttributes[typeof(DeleteAttribute)] != null)
            {
                operationType = ChangeOperation.Delete;
            }
            else
            {
                return TryClassifyUpdateOperationImplicit(method, metadataProvider);
            }

            return operationType;
        }
        /// <summary>
        /// Adds the specified entity type and any associated entity types recursively to the specified set.
        /// </summary>
        /// <param name="entityType">The entity Type to add.</param>
        /// <param name="entityTypes">The types set to accumulate in.</param>
        /// <param name="metadataProvider">The metadata provider.</param>
        private static void AddEntityType(Type entityType, HashSet<Type> entityTypes, MetadataProvider metadataProvider)
        {
            if (entityTypes.Contains(entityType))
            {
                // already added this type
                return;
            }

            entityTypes.Add(entityType);
            RegisterDomainControllerTypeDescriptionProvider(entityType, metadataProvider);

            foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(entityType))
            {
                // for any "exposed" association members, recursively add the associated
                // entity type
                if (pd.Attributes[typeof(AssociationAttribute)] != null && TypeUtility.IsDataMember(pd))
                {
                    Type includedEntityType = TypeUtility.GetElementType(pd.PropertyType);
                    if (metadataProvider.IsEntityType(entityType))
                    {
                        AddEntityType(includedEntityType, entityTypes, metadataProvider);
                    }
                }
            }

            // Recursively add any derived entity types specified by [KnownType]
            // attributes
            IEnumerable<Type> knownTypes = TypeUtility.GetKnownTypes(entityType, true);
            foreach (Type knownType in knownTypes)
            {
                if (entityType.IsAssignableFrom(knownType))
                {
                    AddEntityType(knownType, entityTypes, metadataProvider);
                }
            }
        }