/// <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); }
/// <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); } } }