How to assign default value to a property

試著忘記壹切 提交于 2019-12-02 06:50:17

问题


CustomerService is a webservice and it is getting called successfully but I am unable to access SelectCommand in the Any method. I think I am missing something here, could anyone suggest.

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

I've initialized the connection by inheriting 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);
      }

When I tried to write unit test by setting SelectCommand explicitly, it works. But I am unable to test how it works by not setting the value, I assumed it takes the default value set in the constructor.

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

Edit

IDbConnection in the constructor is working fine but my problem is with SelectCommand which is a public property here. My intention is, if the webservice is called normally I'd hit the actual database by setting query like below in the constructor.

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

But when I test it, I would set it to sqllite database and change my query to table "select * from customers" since sqllite doesn't support sp's. As mentioned unit tests are working fine, but the service is not able to initialize the public properties.

If I initialize a private readonly property same as _dbConnection like below, it works fine but I would like to inject command for the service explicitly.

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

回答1:


Be sure to include all relevant info and context about your question as this would be impossible to infer without out-of-hand knowledge on how you're using it. E.g. what does your IOC look like?

You're asking for an IDbConnection in your constructor:

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

But it's very likely you're only registering an IDbConnectionFactory, so there doesn't exist any registered dependency with IDbConnection.

If you inheriting from Service class you've already got the IDbConnectionFactory injected and access to the IDbConnection with the base.Db property:

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

All public properties get injected by the IOC

The reason why SelectCommand property is null is because it's a public property. All of your Services public properties are attempted to be resolved by your Registered dependencies and because you don't have any registered dependencies of type ServiceCommand it is overrided with null. If this was defined in your constructor instead it would've thrown a run-time exception, because it's just a property it's initialized to null.

If you change the visibility of SelectCommand to protected, private, internal or static it wont be attempted to be injected by the IOC.



来源:https://stackoverflow.com/questions/15745074/how-to-assign-default-value-to-a-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!