1

CustomerService 是一个网络服务,它被成功调用,但我无法在 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 相同的私有只读属性,它可以正常工作,但我想显式地为服务注入命令。

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

1 回答 1

1

请务必包含有关您的问题的所有相关信息和上下文,因为如果没有关于您如何使用它的非手头知识,就无法推断出这一点。例如,您的国际奥委会是什么样的?

IDbConnection你在你的构造函数中要求一个:

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

但很可能你只是注册一个IDbConnectionFactory,所以不存在任何注册的依赖IDbConnection

如果您从Service类继承,您已经通过 base.Db 属性获得了注入IDbConnectionFactory访问权限:IDbConnection

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

所有公共财产都由国际奥委会注入

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

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

于 2013-04-01T15:07:20.800 回答