public DataControllerTypeDescriptionProvider(Type type, MetadataProvider metadataProvider) : base(TypeDescriptor.GetProvider(type)) { if (metadataProvider == null) throw Error.ArgumentNull("metadataProvider"); _type = type; _metadataProvider = metadataProvider; }
/// <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="DataController"/> 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 (DataController).IsAssignableFrom(controllerType)) throw Error.Argument("controllerType", Resource.InvalidType, controllerType.FullName, typeof (DataController).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[] { typeof (MetadataProvider) }) == null) throw Error.InvalidOperation(Resource.MetadataProviderAttribute_MissingConstructor, ProviderType.FullName); return (MetadataProvider) Activator.CreateInstance(ProviderType, parent); }
internal static Metadata.MetadataProvider CreateMetadataProvider(Type dataControllerType) { // construct a list of all types in the inheritance hierarchy for the controller var baseTypes = new List <Type>(); var currType = dataControllerType; while (currType != typeof(DataController)) { baseTypes.Add(currType); Debug.Assert(currType != null, "currType != null"); currType = currType.BaseType; } // create our base reflection provider var providerList = new List <Metadata.MetadataProvider>(); var reflectionProvider = new Metadata.ReflectionMetadataProvider(); // Set the IsEntity function which consults the chain of providers. Func <Type, bool> isEntityTypeFunc = type => providerList.Any(metadataProvider => metadataProvider.LookUpIsEntityType(type)); reflectionProvider.SetIsEntityTypeFunc(isEntityTypeFunc); // Now from most derived to base, create any declared metadata providers, // chaining the instances as we progress. Note that ordering from derived to // base is important - we want to ensure that any providers the user has placed on // their DataController directly come before any DAL providers. Metadata.MetadataProvider currProvider = reflectionProvider; providerList.Add(currProvider); // Reflection rather than TD is used here so we only get explicit // Type attributes. TD inherits attributes by default, even if the // attributes aren't inheritable. foreach (var providerAttribute in baseTypes.SelectMany(type => type.GetCustomAttributes <Metadata.MetadataProviderAttribute>(false))) { currProvider = providerAttribute.CreateProvider(dataControllerType, currProvider); currProvider.SetIsEntityTypeFunc(isEntityTypeFunc); providerList.Add(currProvider); } return(currProvider); }
/// <summary> /// Protected Constructor /// </summary> /// <param name="parent">The existing parent provider. May be null.</param> protected MetadataProvider(MetadataProvider parent) { _parentProvider = parent; }
/// <summary> /// Register our DataControllerTypeDescriptionProvider 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 RegisterDataControllerTypeDescriptionProvider(Type type, Metadata.MetadataProvider metadataProvider) { var tdp = new Metadata.DataControllerTypeDescriptionProvider(type, metadataProvider); RegisterCustomTypeDescriptor(tdp, type); }
/// <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, ICollection <Type> entityTypes, Metadata.MetadataProvider metadataProvider) { if (entityTypes.Contains(entityType)) { // already added this type return; } entityTypes.Add(entityType); RegisterDataControllerTypeDescriptionProvider(entityType, metadataProvider); if (metadataProvider.IsEntityType(entityType)) { TypeDescriptor.GetProperties(entityType) .Cast <PropertyDescriptor>() .Where(pd => pd.HasAttribute <AssociationAttribute>()) .Where(TypeUtility.IsDataMember) .Select(pd => TypeUtility.GetElementType(pd.PropertyType)) .ForEach(t => AddEntityType(t, entityTypes, metadataProvider)); } // Recursively add any derived entity types specified by [KnownType] // attributes TypeUtility.GetKnownTypes(entityType, true) .Where(entityType.IsAssignableFrom) .ForEach(t => AddEntityType(t, entityTypes, metadataProvider)); }