Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# constructor to call constructor after executing code

Tags:

c#

constructor

I've seen answers on constructor chaining but they don't apply for my problem.

I have a the following constructor that requires a couple of parameters:

public SerilogHelper(string conString, int minLevel)
    {
        var levelSwitch = new LoggingLevelSwitch();
        levelSwitch.MinimumLevel = (Serilog.Events.LogEventLevel)(Convert.ToInt32(minLevel));

        _logger = new LoggerConfiguration()
            .MinimumLevel.ControlledBy(levelSwitch)
            .WriteTo.MSSqlServer(connectionString: conString, 
                                 tableName: "Logs", 
                                 autoCreateSqlTable: true)
            .CreateLogger();
    }

One particular client of this constructor won't have the values required for the parameters so I'd like to be able to call this simple constructor which would get the required values then call the 1st constructor:

public SerilogHelper()
    {
        string minLevel = SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
          "LCC.Common", "serilog.level");
        string conString = SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
          "LCC.Common", "serilog.connectionstring");

        SerilogHelper(conString, minLevel);
    }

Problem is, I get a red squiggly on the call to the 2nd constructor with the message SerilogHelper is a 'type' but used like a 'variable'

like image 283
Rob Bowman Avatar asked Jun 20 '17 10:06

Rob Bowman


2 Answers

Why not just simply add these parameters?

// this assumes that SSOSettingsFileManager is static class
// this will automatically call these methods before passing 
// values to another ( non parameterless ) constructor
public SerilogHelper()
    : this ( 
        SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
            "LCC.Common", "serilog.connectionstring"
        ),
        SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
            "LCC.Common", "serilog.level"
        )
    )
{

}

// This will be called from default ( parameterless )
// constructor with values retrieved from methods
// called in previous constructor.
public SerilogHelper(string conString, int minLevel)
{
        var levelSwitch = new LoggingLevelSwitch();
        levelSwitch.MinimumLevel = (Serilog.Events.LogEventLevel)(Convert.ToInt32(minLevel));

        _logger = new LoggerConfiguration()
            .MinimumLevel.ControlledBy(levelSwitch)
            .WriteTo.MSSqlServer(connectionString: conString, 
                                 tableName: "Logs", 
                                 autoCreateSqlTable: true)
            .CreateLogger();
}

Test online

like image 195
Mateusz Avatar answered Nov 01 '22 06:11

Mateusz


You cannot do that. The best option you have it so move the initialization code to a separate method which you can call from both the constructors. That is allowed.

public SerilogHelper()
{
    string minLevel = SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
      "LCC.Common", "serilog.level");
    string conString = SSOSettingsFileManager.SSOSettingsFileReader.ReadString(
      "LCC.Common", "serilog.connectionstring");

    this.Initialize(conString, minLevel);
}

public SerilogHelper(string conString, int minLevel)
{
    this.Initialize(conString, minLevel);
}

protected void Initialize(string conString, int minLevel)
{
    var levelSwitch = new LoggingLevelSwitch();
    levelSwitch.MinimumLevel = (Serilog.Events.LogEventLevel)(Convert.ToInt32(minLevel));

    _logger = new LoggerConfiguration()
        .MinimumLevel.ControlledBy(levelSwitch)
        .WriteTo.MSSqlServer(connectionString: conString, 
                             tableName: "Logs", 
                             autoCreateSqlTable: true)
        .CreateLogger();
}
like image 34
Patrick Hofman Avatar answered Nov 01 '22 06:11

Patrick Hofman