在ServiceStack Web服务中设置公共属性

时间:2013-04-01 19:04:58

标签: servicestack

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

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

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

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

ServiceCommand

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

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

为了能够运行测试用例和服务,我修改了Any()方法来实例化ServiceCommand,如果它是null。我想知道这是否可行,或者是否有更好的选择。

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

  }
}

1 个答案:

答案 0 :(得分:1)

由于ServiceStack服务将为所有公共属性注入已注册的IOC属性,它将覆盖您在构造函数中设置的值,因此如果不在IOC中注册它,则无法将其设置为公共属性,因为它将被覆盖为空。

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

将其设为公共字段

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