Net 8.0: переход от сериализации в источники генераторовC#

Место общения программистов C#
Ответить
Anonymous
 Net 8.0: переход от сериализации в источники генераторов

Сообщение Anonymous »

Мы находимся в процессе миграции существующего блазора WASM (размещенного в приложении ASP.NET Core) в Net 8.0, и у нас есть несколько проблем с обрезкой (и как это работает). Одним из них является обеспечение того, чтобы триммер не удалял типы, используемые для взаимодействия с веб -API, потребляемым приложением Blazor Wasm. В настоящее время сериализация/десеризация полагается на System.text.json (база отражения и отсутствие обрезки). Теоретически, переход от размышлений к генераторам источников не должно быть таким тяжелым. К сожалению, кажется, что это один из тех сценариев, где теория не совсем соответствует тому, что происходит в реальном мире.

Код: Выделить всё

public sealed record Descriptor(T Value, string Description);
В проекте мы переносим, ​​этот тип используется несколькими из конечных точек API для возврата значений Enum/пар, показанных несколькими раскрывающимися списками, которые существуют на разных страницах, представленных Blazor Wasm UI. Частичный jsonerializercontext Полученный тип. Futhermore, кажется, что вы не можете указать открытый общий тип, поэтому, если вы используете этот общий тип с Enums Kind и Kindb, вам придется хотя бы иметь это: < /p>

Код: Выделить всё

[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(Descriptor))]
[JsonSerializable(typeof(Descriptor))]
public partial class DescriptorContext: JsonSerializerContext{}
< /code>
Теперь, когда у вас есть несколько типов перечисления, это не красиво. Тем не менее, кажется, что вам также нужно добавить записи, если вы хотите сериализовать коллекции каждого типа дескриптора: < /p>
[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(Descriptor))]
[JsonSerializable(typeof(IEnumerable))]
[JsonSerializable(typeof(List))]
// removed entries for  KindB
public partial class DescriptorContext: JsonSerializerContext{}
Другими словами, без этих записей я не могу сериализовать/десериализовать ienumerable или list экземпляры, подобные тем, которые показаны в следующем примере:

List items =
[
new(Kind.Single, "Single"),
new(Kind.Colective, "Colective")
];
string serialized = JsonSerializer.Serialize
(
items,
DescriptorContext.Default.ListDescriptorKind
);
List recovered = JsonSerializer.Deserialize
(
serialized,
DescriptorContext.Default.ListDescriptorKind
)!;

foreach (Descriptor item in recovered)
{
Console.WriteLine($"{item.Value} {item.Description}");
}
< /code>
Это правильно? Я имею в виду, правильно ли заключить, что:
  • Вы не можете указать открытый тип
  • Вы должны указать все типы, которые вы хотите сериализовать/пустынь через JsonserializableAttribute , включая закрытые общины, такие как то, что показано на предыдущей Snippet (Ex. Список )
Я действительно надеюсь, что я что-то упускаю здесь, потому что, если использование источников требует всех этих строк, то действительно трудно использовать их в любом проекте среднего размера ... если вы смотрите на этот пример, я бы сказал, что поддержание jsonserializableattrubite не проще. что у нас нет исходного кода для сборки, которая имеет типы, используемые веб -API, который потребляется приложением Blazor Wasm. Первоначально, json.net использовался для сериализации/десериализации, а API имеет несколько конечных точек, в которых тип возврата представляет собой производный тип типа, указанного на подписи метода контроллера (полиморфизм):

public async Task DoSomething()
{
// always returns an instance of a Base's derived type
}
< /code>
Первоначально сериализация была сделана с помощью json.net. Тем не менее, мы закончили тем, что перешли на System.text.json, когда он официально поддерживает наследование. В то время мы в итоге прибегли к пользовательскому DefaultJsontypeinforesolver , чтобы используемый дискриминатор совместим с тем, что сгенерирован по умолчанию json.net (имя свойства установлено в $ type , а его значение является квалифицированным именем с полной сборкой). Это потребовалось, потому что некоторые из типов, используемых в API, также сохранялись в базе данных. Вот некоторый демонстрационный код, используемый для defaultjsontypeinforesolver :

Код: Выделить всё

public class JsonHierarchyTypeInfoResolver : DefaultJsonTypeInfoResolver
{
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
var jsonTypeInfo = base.GetTypeInfo(type, options);
var jsonType = jsonTypeInfo.Type;

if (jsonType == typeof(Equipamento))
{
jsonTypeInfo = GetTypeInfoForDevice(jsonTypeInfo);
}
// ... remaining code removed
}

private static JsonTypeInfo GetTypeInfoForDevice(JsonTypeInfo jsonTypeInfo)
{
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
{
TypeDiscriminatorPropertyName = "$type",
IgnoreUnrecognizedTypeDiscriminators = true,
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization
};

foreach (var jsonDerivedType in _derivedDevicesTypes)
{
jsonTypeInfo.PolymorphismOptions.DerivedTypes.Add(
new JsonDerivedType(jsonDerivedType,
jsonDerivedType.AssemblyQualifiedName!));
}

return jsonTypeInfo;
}
}
< /code>
Итак, окончательные 2 вопроса: < /p>
[list]
[*] Можно ли объединить этот резоливер с тем, что сгенерировано генераторами источников? Или они работают только с полиморфными атрибутами (Ex.: Jsonderivedtypeattribute 
)
[*] Если нет, то это означает, что мне придется переписать новую сборку DTO, которая использует полиморфные атрибуты, чтобы повторно использовать API, на основе Polymorphism/inherishance (i.e. Полученные типы)?
[/list]

Подробнее здесь: https://stackoverflow.com/questions/778 ... generators
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»