【问题标题】:static class configuration for service fabric actors服务结构参与者的静态类配置
【发布时间】:2020-04-11 07:52:56
【问题描述】:

Service Fabric Actor 用于访问数据库,所有方法都假设使用 Dapper 作为 ORM 工具。

我发现解决当前问题的最佳方法是在 Dapper 中使用称为 SqlMapper 的东西。这样,您可以定义处理某些数据类型的一般行为,例如:

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();
    }
}

当您使用 DateTimeHandler 等自定义处理程序声明上述静态方法 (AddTypeHandler) 时,使用 Dapper 框架完成的映射将确保任何 dateTime 类型正确地通过上述处理程序。

我希望看到这种情况发生在每个 Actor 通过 Dapper 与数据库通信时。 我还没有看到它在尝试使用几个不同的地方(例如 Actor constructor() 或下面的 main 方法)声明上面的静态方法:

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;
        }
} 

【问题讨论】:

    标签: c# dapper service-fabric-actor


    【解决方案1】:

    我通常不想回答我自己的问题,但这是我目前发现的。

    首先,如果我希望解决问题的实际解决方案与标题本身更相关,我可能需要更改此问题的标题。但是,由于标题问题已在此帖子中得到解答,因此我将保持原样。

    简单地说,静态类的配置可以在我上面提到的所有地方完成,例如 Actor 构造函数、OnActivateAsync() 等,因为静态类仍然在不同的线程之间共享(Actor 都是单个独立的线程)在 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();
    

    【讨论】:

      猜你喜欢
      • 2017-12-08
      • 2018-03-06
      • 2019-12-01
      • 2016-06-12
      • 2018-04-11
      • 2017-07-09
      • 2017-03-12
      • 2016-06-17
      • 2015-08-03
      相关资源
      最近更新 更多