Акаваче не хранит / не возвращает NodaTime LocalDateTime - PullRequest
0 голосов
/ 12 июня 2019

Мне нужно хранить NodaTime LocalDateTime в кэше Akavache.

Я создал простое приложение, которое берет следующий класс и сохраняет / получает его в / из кэша Akavache:

public class TestModel
{
        public string Name { get; set; }
        public LocalDateTime StartDateTimeLocal {get; set;}
        public DateTime StartDateTimeUtc {get;set;}
}

Когда это сохраняется и извлекается из кэша, свойство StartDateTimeLocal не заполняется.

Кажется, что Akavache не знает, как сериализовать / десериализовать LocalDateTime.

Можно ли зарегистрировать типы в Akavache или предоставить настраиваемую сериализацию для неизвестных типов?

Консольное приложение для демонстрации:

using Akavache;
using NodaTime;
using System;
using System.Reactive.Linq;

namespace AkavacheNodaTimeCore
{
    class Program
    {
        static TestModel BeforeModel;
        static TestModel AfterModel;
        static void Main(string[] args)
        {
            // Note that we're using Akavache 6.0.27, to match the version we're using in our live system.
            BlobCache.ApplicationName = "AkavacheNodaTimeCore";
            BlobCache.EnsureInitialized();

            BeforeModel = new TestModel()
            {
                StartLocalDateTime = LocalDateTime.FromDateTime(DateTime.Now),
                StartDateTime = DateTime.UtcNow,
            };

            Console.WriteLine($"Before:LocalDateTime='{BeforeModel.StartLocalDateTime}' DateTime='{BeforeModel.StartDateTime}'");

            CycleTheModels();

            Console.WriteLine($"After: LocalDateTime='{AfterModel.StartLocalDateTime}' DateTime='{AfterModel.StartDateTime}'");
            Console.WriteLine("Note that Akavache retrieves DateTimes as DateTimeKind.Local, so DateTime before and after above will differ.");

            Console.WriteLine("Press any key to continue.");
            var y = Console.ReadKey();

        }
        /// <summary>
        /// Puts a model into Akavache and retrieves a new one so we can compare.
        /// </summary>
        static async void CycleTheModels()
        {
            await BlobCache.InMemory.Invalidate("model");
            await BlobCache.InMemory.InsertObject("model", BeforeModel);

            AfterModel = await BlobCache.InMemory.GetObject<TestModel>("model");
        }
    }
}

Класс TestModel:

using NodaTime;
using System;

namespace AkavacheNodaTimeCore
{
    public class TestModel
    {
        public string Name { get; set; }
        public LocalDateTime StartLocalDateTime { get; set; }
        public DateTime StartDateTime {get;set;}

    }
}

Я добавил Git repo с вышеупомянутым в консольном приложении, которое демонстрирует проблему.

1 Ответ

2 голосов
/ 13 июня 2019

Вам необходимо настроить JsonSerializerSettings, который Akavache использует с Json.NET.Вам понадобится ссылка на NodaTime.Serialization.JsonNet, после чего вы сможете создать экземпляр параметров сериализатора, настроить его для Noda Time, а затем добавить его в качестве зависимости в Splat (который использует Akavache).Я раньше не пользовался Splat, поэтому возможно, что это неправильный способ, но он работает с вашим примером:

using Newtonsoft.Json;
using NodaTime.Serialization.JsonNet;
using Splat;

...

// This should be before any of your other code.
var settings = new JsonSerializerSettings();
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
Locator.CurrentMutable.RegisterConstant(settings, typeof(JsonSerializerSettings));

Возможно, стоит подать вопрос в репо Akavacheзапросить дополнительную документацию для настройки параметров сериализации - все вышеперечисленное работает, но это были догадки и небольшое изучение исходного кода.

...