protected sealed override async Task <TSubject> DoMaterializeAsync(ISubjectLoadContext ctx, StreamInfo stream) { var fileLoadCtx = ctx.Arg(nameof(ctx)).EnsureOfType <ISubjectLoadContext, ISubjectFileLoadContext>().Value; // return(await DoMaterializeAsync(context : fileLoadCtx, stream : stream).ConfigureAwait(false)); }
protected override async Task <IVh <StreamInfo> > GetSourceStreamAsync(ISubjectLoadContext ctx) { ctx.EnsureNotNull(nameof(ctx)); // await Task.CompletedTask; // Stream sourceStream = default; try { sourceStream = ResourceUtilities.RequireManifestResourceStream(uri: ctx.BaseUri.ArgProp($"{nameof(ctx)}.{nameof(ctx.BaseUri)}"), resourceName: out var resourceName); string mediaType; if (resourceName.EndsWith(value: DescriptionPackageConstants.PackageXmlFormatFileExtension, comparisonType: StringComparison.OrdinalIgnoreCase)) { mediaType = MediaTypeNameUtilities.AppXml; } else if (resourceName.EndsWith(value: DescriptionPackageConstants.PackageJsonFormatFileExtension, comparisonType: StringComparison.OrdinalIgnoreCase)) { mediaType = MediaTypeNameUtilities.AppJson; } else { mediaType = default; } return(new StreamInfo(stream: sourceStream, ownsStream: true, contentMediaType: mediaType).ToValueHolder(ownsValue: true)); } catch { sourceStream?.Dispose(); throw; } }
// TODO: Put strings into the resources. // protected virtual async Task <TSubject> DoMaterializeAsync(ISubjectLoadContext ctx, StreamInfo stream) { ctx.EnsureNotNull(nameof(ctx)); stream.EnsureNotNull(nameof(stream)); // await Task.CompletedTask; TSubject subject; var deserializedObjectAsIDisposable = default(IDisposable); try { object deserializedObject; if (IsJsonMediaType(mediaTypeName: stream.ContentMediaType)) { // JSON. // var jsonSerializer = ctx.CreateJsonSerializer(); using (var textReader = new StreamReader(stream.Stream, Encoding.UTF8, true, TextReaderWriterUtilities.DefaultBufferSize, true)) using (var jsonReader = new JsonTextReader(textReader)) deserializedObjectAsIDisposable = (deserializedObject = jsonSerializer.Deserialize(jsonReader)) as IDisposable; } else if (IsXmlMediaType(mediaTypeName: stream.ContentMediaType)) { // XML. // var xmlObjectSerializer = ctx.CreateXmlObjectSerializer(type: typeof(object)); using (var xmlReader = XmlReader.Create(input: stream.Stream, settings: ctx.CreateXmlReaderSettings().CopyWith(closeInput: false))) deserializedObjectAsIDisposable = (deserializedObject = xmlObjectSerializer.ReadObject(xmlReader, false)) as IDisposable; } else { throw new NotSupportedException($"Медиа-тип содержимого потока не поддерживается.{Environment.NewLine}\tМедиа-тип:{stream.ContentMediaType.FmtStr().GNLI2()}"); } // subject = deserializedObject as TSubject; if (subject is null && !(deserializedObject is null)) { throw new EonException(message: $"Десериализованный объект имеет тип, не совместимый с требуемым.{Environment.NewLine}\tТип десериализованного объекта:{deserializedObject.GetType().FmtStr().GNLI2()}{Environment.NewLine}\tТребуемый тип:{typeof(TSubject).FmtStr().GI2()}."); } // return(subject); } catch (Exception exception) { DisposeMany(exception: exception, disposables: deserializedObjectAsIDisposable); throw; } }
// TODO: Put strings into the resources. // protected virtual async Task <IVh <StreamInfo> > RecognizeMediaFormatAsync(ISubjectLoadContext ctx, Stream stream) { var isJson = P_TryRecognizeStreamContentAsJson(stream); if (isJson) { return(new StreamInfo(stream, false, contentMediaType: AppJson).ToValueHolder(true)); } else { var isXml = await P_TryRecognizeStreamContentAsXmlAsync(stream, ctx.CreateXmlReaderSettings()).ConfigureAwait(false); if (isXml) { return(new StreamInfo(stream, false, contentMediaType: AppXml).ToValueHolder(true)); } else { throw new NotSupportedException(message: $"Формат содержимого потока не распознан или не поддерживается.{Environment.NewLine}\tКомпонент:{this.FmtStr().GNLI2()}{Environment.NewLine}\tКонтекст:{ctx.FmtStr().GNLI2()}{Environment.NewLine}\tПоток:{stream.FmtStr().GNLI2()}"); } } }
protected abstract Task <IVh <StreamInfo> > GetSourceStreamAsync(ISubjectLoadContext context);
ITaskWrap <TSubject> ISubjectMaterializer <TSubject> .MaterializeAsync(ISubjectLoadContext ctx) => MaterializeAsync(ctx).Wrap();
// TODO: Put strings into the resources. // public async Task <TSubject> MaterializeAsync(ISubjectLoadContext ctx) { var gotStreamInfoStore = default(IVh <StreamInfo>); var recognizedStreamInfoStore = default(IVh <StreamInfo>); var materializedSubject = default(TSubject); var caughtException = default(Exception); try { // Получить поток загрузки. // gotStreamInfoStore = await GetSourceStreamAsync(context : ctx).ConfigureAwait(false); var useStreamInfo = gotStreamInfoStore.Value; // if (IsGenericMediaType(useStreamInfo.ContentMediaType)) { // Распознать конкретный медиа-тип содержимого потока загрузки (т.е. отличный от универсального). // recognizedStreamInfoStore = await RecognizeMediaFormatAsync(ctx, useStreamInfo.Stream).ConfigureAwait(false); useStreamInfo = recognizedStreamInfoStore.Value; } // Если контекстом загрузки указан медиа-тип, отличный от универсального, то медиа-тип потока загрузки должен соответствовать указанному в контексте загрузки. // if (!IsGenericMediaType(ctx.MediaType) && !useStreamInfo.ContentMediaType.EqualsOrdinalCI(ctx.MediaType)) { throw new EonException($"Медиа-тип содержимого потока загрузки не соответствует требуемому медиа-типу контекста загрузки.{Environment.NewLine}\tМедиа-тип потока загрузки:{Environment.NewLine}{useStreamInfo.ContentMediaType.IndentLines2()}{Environment.NewLine}\tМедиа-тип контекста загрузки:{ctx.MediaType.IndentLines2()}."); } // Материализация (десериализация). // materializedSubject = await DoMaterializeAsync(ctx : ctx, stream : useStreamInfo).ConfigureAwait(false); // var siteOriginSupport = materializedSubject as ISiteOriginSupport; if (siteOriginSupport?.HasSiteOrigin == false) { siteOriginSupport.SetSiteOrigin(siteOrigin: ctx.SiteOrigin); } // return(materializedSubject); } catch (Exception exception) { caughtException = exception; throw; } finally { if (caughtException != null) { DisposeManyDeep(caughtException, materializedSubject); } try { recognizedStreamInfoStore?.Dispose(); gotStreamInfoStore?.Dispose(); } catch (Exception exception) { if (caughtException == null) { throw; } else { throw caughtException.ToAggregateException(exception); } } } }
protected sealed override async Task <IVh <StreamInfo> > RecognizeMediaFormatAsync(ISubjectLoadContext ctx, Stream stream) { var fileLoadContext = ctx.Arg(nameof(ctx)).EnsureOfType <ISubjectLoadContext, ISubjectFileLoadContext>().Value; // return(await RecognizeMediaFormatAsync(fileLoadContext, stream).ConfigureAwait(false)); }
protected sealed override async Task <IVh <StreamInfo> > GetSourceStreamAsync(ISubjectLoadContext ctx) { var fileLoadContext = ctx.Arg(nameof(ctx)).EnsureOfType <ISubjectLoadContext, ISubjectFileLoadContext>().Value; // return(await GetSourceStreamAsync(fileLoadContext).ConfigureAwait(false)); }