public static MediaTypeConfiguration <TEntityType> MediaType <TEntityType>(this EntityTypeConfiguration <TEntityType> configuration, Expression <Func <TEntityType, string> > propertyExpression) where TEntityType : class { Arg.NotNull(configuration, nameof(configuration)); Arg.NotNull(propertyExpression, nameof(propertyExpression)); Contract.Ensures(Contract.Result <MediaTypeConfiguration <TEntityType> >() != null); // an entity that represents a media type can only have a single link entry. check for presense of an existing configuration. var key = propertyExpression.GetMediaResourceKey(); var builder = configuration.GetModelBuilder(); var configurations = builder.GetAnnotationConfigurations(); MediaTypeConfiguration <TEntityType> mediaTypeConfig; // if the media type has already been configured, return the existing configuration if (configurations.TryGet(key, out mediaTypeConfig)) { return(mediaTypeConfig); } // always ignore the content type property from the entity model and call the build-in MediaType // extension method, which will configure the entity model with HasStream = true for the entity propertyExpression.IgnoredBy(configuration); configuration.MediaType(); // compile the property expression into a lazy-initialized, contravariant function // we do this so that we don't have to use reflection later to get the content type // nor require the developer to write explicit code to get the value var contentType = new Lazy <Func <object, string> >(() => { var func = propertyExpression.Compile(); return(o => { try { return func((TEntityType)o); } catch (NullReferenceException) { // note: this is supported so we gracefully fail and do not return a value for an expression // that refers to a object graph path. for example: r => r.Image.Type, where Image could be null. // also note that the null propagtion operator cannot be used in an expression. for example: // the following expression will not compile: r => r.Image?.Type. return null; } }); }); var annotation = new MediaLinkEntryAnnotation(contentType); mediaTypeConfig = new MediaTypeConfiguration <TEntityType>(configuration, annotation); configurations.Add(key, mediaTypeConfig); return(mediaTypeConfig); }
public static MediaTypeConfiguration <TEntityType> MediaType <TEntityType>(this EntityTypeConfiguration <TEntityType> configuration, string contentType) where TEntityType : class { Arg.NotNull(configuration, nameof(configuration)); Contract.Ensures(Contract.Result <MediaTypeConfiguration <TEntityType> >() != null); var key = typeof(TEntityType).FullName + ".MediaType"; var builder = configuration.GetModelBuilder(); var configurations = builder.GetAnnotationConfigurations(); MediaTypeConfiguration <TEntityType> mediaTypeConfig; if (configurations.TryGet(key, out mediaTypeConfig)) { return(mediaTypeConfig); } configuration.MediaType(); var annotation = new MediaLinkEntryAnnotation(instance => contentType); mediaTypeConfig = new MediaTypeConfiguration <TEntityType>(configuration, annotation); configurations.Add(key, mediaTypeConfig); return(mediaTypeConfig); }