конфигурация статического класса для субъектов Service Fabric

Субъекты Service Fabric используются для доступа к базе данных, и все методы предполагают использование Dapper в качестве инструмента ORM.

Одна вещь, которую я обнаружил, лучший способ решить текущую проблему — это использовать что-то под названием SqlMapper в Dapper. При этом вы можете определить общее поведение при обработке определенных типов данных, например:

SqlMapper.AddTypeHandler(new DateTimeHandler());

public class DateTimeHandler : SqlMapper.TypeHandler<DateTime>
{
    public override void SetValue(IDbDataParameter parameter, DateTime dateTime)
    {
        parameter.Value = dateTime.ValidateDateTime();
    }

    public override DateTime Parse(object value)
    {
        return ((DateTime)value).ValidateDateTime();
    }
}

Поскольку вы объявляете статический метод выше (AddTypeHandler) с настраиваемым обработчиком, таким как DateTimeHandler, сопоставление, выполненное с использованием платформы Dapper, гарантирует, что любой тип dateTime проходит через вышеуказанный обработчик правильно.

Я бы хотел, чтобы это происходило, когда каждый Актер общается с базой данных через Dapper. Я еще не видел, чтобы это происходило при объявлении вышеуказанного статического метода в попытках с несколькими разными местами, такими как конструктор Actor() или основной метод, такой как ниже:

private static void Main()
{
        try
        {
            // This line registers an Actor Service to host your actor class with the Service Fabric runtime.
            // The contents of your ServiceManifest.xml and ApplicationManifest.xml files
            // are automatically populated when you build this project.
            // For more information, see https://aka.ms/servicefabricactorsplatform

            ActorRuntime.RegisterActorAsync<SqlRepositoryActor>(
               (context, actorType) => new ActorService(context, actorType)).GetAwaiter().GetResult();

            // This doesn't seem like a right place as I don't see the handler being called when Actor uses dapper mapping methods.
            SqlMapper.AddTypeHandler(new DateTimeHandler());

            Thread.Sleep(Timeout.Infinite);
        }
        catch (Exception e)
        {
            ActorEventSource.Current.ActorHostInitializationFailed(e.ToString());
            throw;
        }
} 

person swcraft    schedule 18.12.2019    source источник


Ответы (1)


Обычно я не хочу отвечать на свой вопрос, но вот что я узнал на данный момент.

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

Чтобы дать краткий ответ, конфигурация статического класса может быть выполнена со всеми местами, которые я упомянул выше, такими как конструктор актера, OnActivateAsync() и т. д., поскольку статический класс по-прежнему используется в разных потоках (все актеры — это отдельные независимые потоки) в AppDomain. (Акторы работают внутри AppDomain. Пожалуйста, поправьте меня, если я ошибаюсь.)

Что на самом деле вызвало указанную выше проблему, так это то, что определение сопоставления с использованием Dapper было объявлено как динамическое; показано ниже:

return sqlConnection.Query<dynamic>(some_sql_script, new { objInstance }).FirstOrDefault();

Как только вы измените ожидаемый возвращаемый тип T на сильный тип, который содержит тип typeHandler, Dapper правильно вызовет typeHandler:

return sqlConnection.Query<StrongType>(some_sql_script, new { objInstance }).FirstOrDefault();
person swcraft    schedule 20.12.2019