在 ServiceStack Web 服务中设置公共属性 [英] Set public properties in ServiceStack web services

查看:54
本文介绍了在 ServiceStack Web 服务中设置公共属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Sqlite 为 ServiceStack 服务编写单元测试.由于 Sqlite 不支持存储过程,我创建了类型为ServiceCommand"的公共属性,它将命令文本和命令类型作为输入.默认情况下,它被配置为运行存储过程,在编写单元测试用例时,我在调用 Any() 方法之前将 SelectCommand 属性重新分配给针对 sqlite 的 sql 查询,如下所示.所有测试用例都可以正常工作.

I am trying to write unit tests for ServiceStack services using Sqlite. Since Sqlite doesn't support stored procedures, I've created public property of type 'ServiceCommand' that takes command text and command type as inputs. By default it is configured to run stored procedure and while writing unit test cases, I am re-assigning the SelectCommand property to sql query against sqlite before calling Any() method as below. All test cases work fine.

var request = new CustomerRequest() { name = "alfki"  };
var service = new CustomerService(InMemoryTestDatabase.OpenDbConnection());
service.SelectCommand = new ServiceCommand() { SQL = "SELECT * FROM customers where customerid = {0}" };
var result = service.Any(request);

但根据此线程,CustomerService 的公共属性在解析引用时被 IOC 设置为 null,因此 Any() 方法中的 SelectCommand 为 null,导致对象引用错误.通过将属性设置为 protected、private、internal 或 static,我将无法运行单元测试.

But per this thread, public properties of CustomerService are set to null by IOC while resolving the references thus SelectCommand is null in Any() method resulting in object reference error. By setting the property as protected, private, internal or static, I will not be able to run unit tests.

public class CustomerService : Service
{
  private readonly IDbConnection _dbConnection;
  public ServiceCommand SelectCommand {get;set;}

  public CustomerService(IDBConnection dbConnection)
  {        
         _dbConnection = dbConnection;  //injected successfully
         SelectCommand =  new ServiceCommand(){ SQL = "sp_getcustomers",
            CommandType = CommandType.StoredProcedure};          
  }

  public Customer Any(CustomerRequest request)
  {
        //Select command is not accessible here.

  }
}


[Route("/customers")]
public class CustomerRequest
{
    public string name { get; set; }
}

服务命令

public class ServiceCommand
{
    public string SQL { get; set; }        
    public CommandType CommandType { get; set; }

    public ServiceCommand()
    {
        CommandType = CommandType.Text;
    }
}

为了能够同时运行测试用例和服务,我修改了 Any() 方法以在 ServiceCommand 为空时实例化它.我想知道这是要走的路还是有更好的选择.

To be able to run test cases and service as well, I've modified Any() method to instantiate ServiceCommand if it is null. I would like to know if this is the way to go or any better alternatives.

public class CustomerService : Service
{
  private readonly IDbConnection _dbConnection; // injected successfully
  public ServiceCommand SelectCommand {get;set;}

  public CustomerService(IDBConnection dbConnection)
  {        
         _dbConnection = dbConnection;  //injected successfully         
  }

  public Customer Any(CustomerRequest request)
  {
        SelectCommand = SelectCommand ?? new ServiceCommand() { SQL = "sp_getCustomers",CommandType = CommandType.StoredProcedure };

  }
}

推荐答案

由于 ServiceStack 服务会注入已注册的 IOC所有公共属性的属性,它将覆盖您在构造函数中设置的值,因此您无法在不将其注册到 IOC 的情况下将其设为公共属性,因为它将被覆盖为 null.

Since ServiceStack services will inject registered IOC properties for all public properties it will override the value you set in the constructor so you can't make it a public property without registering it in the IOC since it will be overridden to null.

鉴于此,一些可能的选择是:

Given this, some possible options are:

public class CustomerService : Service
{
    public ServiceCommand SelectCommand = new ServiceCommand { 
       SQL = "sp_getcustomers", 
       CommandType = CommandType.StoredProcedure };
    ...
}

使用 setter 注入只读属性

service.SetSelectCommand(
  new ServiceCommand { SQL = "SELECT * FROM customers where customerid = {0}" });

在你的 IOC 中注册并在你的构造函数中指定它

container.Register(new ServiceCommand { 
   SQL = "sp_getcustomers", 
   CommandType = CommandType.StoredProcedure });

并将构造函数更改为:

public CustomerService(IDBConnection dbConnection, ServiceCommand serviceCommand)
{        
    _dbConnection = dbConnection; 
    _serviceCommand = serviceCommand;    
}

这篇关于在 ServiceStack Web 服务中设置公共属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆