如何为属性指定默认值

时间:2013-04-01 14:13:26

标签: c# c#-4.0 servicestack

CustomerService是一个Web服务,它已成功调用,但我无法在Any方法中访问SelectCommand。我想我在这里遗漏了一些东西,有人可以建议。

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

  public CustomerService(IDBConnection dbConnection)
  {        
         _dbConnection = dbConnection;            
  }

  public Customer Any(CustomerRequest request)
  {
       //_dbconnection is available           

       //but selectcommand is null here   

       //db operations     

  }
}


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

我通过继承AppHostBase

初始化了连接
  public override void Configure(Container container) {
        container.Register<IDbConnectionFactory>(
          c => new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["default"].ConnectionString,
                                            SqlServerDialect.Provider));

        container.Register<IDbConnection>(c => c.Resolve<IDbConnectionFactory>().OpenDbConnection()).ReusedWithin(ReuseScope.Request);
      }

当我尝试通过显式设置SelectCommand来编写单元测试时,它可以工作。但我无法通过不设置值来测试它是如何工作的,我假设它采用了构造函数中设置的默认值。

 var service = new CustomerService(InMemoryTestDatabase.OpenDbConnection());
 service.SelectCommand = new ServiceCommand() { SQL = "SELECT * FROM customers" };

修改

构造函数中的IDbConnection工作正常但我的问题在于SelectCommand,这是一个公共属性。我的意图是,如果正常调用web服务,我会通过在构造函数中设置如下所示的查询来点击实际的数据库。

SelectCommand = new ServiceCommand() {Text = "sp_getcustomers"};

但是当我测试它时,我会将它设置为sqllite数据库并将我的查询更改为表“select * from customers”,因为sqllite不支持sp。如上所述,单元测试工作正常,但服务无法初始化公共属性。

如果我像下面一样初始化一个与_dbConnection相同的私有readonly属性,它可以正常工作,但我想明确地为服务注入命令。

private readonly IDbConnection _dbConnection;
private readonly ServiceCommand _selectCommand;
public CustomerService(IDBConnection dbConnection)
{
   __dbConnection = dbConnection;
   _selectCommand = new ServiceCommand(){Text = "sp_getCustomers"};
}

1 个答案:

答案 0 :(得分:1)

请务必提供有关您问题的所有相关信息和背景信息,因为如果没有关于您如何使用它的现有知识,就无法推断出这一点。例如。你的国际奥委会是什么样的?

你在构造函数中要求IDbConnection

public CustomerService(IDBConnection dbConnection)
{
     SelectCommand = new ServiceCommand();
}

但很可能你只注册IDbConnectionFactory,因此IDbConnection没有任何已注册的依赖项。

如果您继承了Service课程,那么您已经注入了IDbConnectionFactory并且可以使用base.Db property访问IDbConnection

private IDbConnection db;
public virtual IDbConnection Db
{
    get { return db ?? (db = TryResolve<IDbConnectionFactory>().Open()); }
}

所有公共财产都由IOC注入

SelectCommand 属性为null的原因是因为它是公共属性。尝试通过已注册的依赖项解析所有服务公共属性,并且因为您没有任何类型为ServiceCommand的已注册依赖项,所以它将被覆盖为null。如果这是在你的构造函数中定义的,那么它会抛出一个运行时异常,因为它只是一个属性,它被初始化为null。

如果您将SelectCommand的可见性更改为受保护,私有,内部或静态,则不会尝试由IOC注入。