Reputation: 231
Problem
When I instantiate an instance of the Service class - derived from the ServiceBase class - the constructor I create for the Service class is skipped during instantiation. Then when the line "private ServiceController controller..." is hit, it fails because the ConfigStream object is never passed to the Service class variable _configstream. I don't have issues with constructors being skipped elsewhere in my code. Is this related to the use of the base class ServiceBase?
I've tried including the base class constructor like:
public Service(ConfigStream configstream) : base() {}
It doesn't produce any different result. From what I've read, that makes sense because the default constructor of the base class should be called by default.
I've included the beginning of both my Service class and ConfigStream. ConfigStream utilizes its constructors without any issue, but its also not inheriting any classes.
Code
public static class MainClass
{
static void Main(String[] args)
{
// Test if input arguments were supplied
if (args.Length > 0)
{
// if arguments supplied, use the supplied config file path (second cli argument)
if (args[0] == "-i")
{
// ConfigStream configstream = new ConfigStream(args[1]);
ServiceBase.Run(new Service(new ConfigStream(args[1])));
}
}
else
{
// otherwise run service without arguments
// the config will be assumed in the same directory
Service service = new Service(new ConfigStream());
ServiceBase.Run(service);
}
}
}
public class Service : ServiceBase
{
// class instantiation
private Thread processThread;
private Process process;
// Instance variables
private static ConfigStream _configstream;
// Function: Service
// Purpose: Class Constructor
public Service(ConfigStream configstream)
{
// assign ConfigStream instance
_configstream = configstream;
// set global service name and description for use by installer
GlobalVariables.setServicename(_configstream.getSetting("Service Name"));
GlobalVariables.setServicedesc(_configstream.getSetting("Service Description"));
ServiceName = _configstream.getSetting("Service Name");
//setting logger level
logger.setLogLevel(0);
logger.info("System Event", "Starting service");
processThread = new Thread(ProcessManager);
processThread.Start();
}
private ServiceController controller = new ServiceController(_configstream.getSetting("Service
Name"));
...
}
public class ConfigStream
{
// set properties of ConfigStream
public string config { get; private set; }
// constructor with config as an argument
public ConfigStream(string config_location)
{
string config = config_location;
}
// constructor with no arguments
public ConfigStream()
{
config = GlobalVariables.cwd + "\\" + GlobalVariables.configFileName;
}
...
}
Upvotes: 0
Views: 236
Reputation: 27974
When I instantiate an instance of the Service class - derived from the ServiceBase class - the constructor I create for the Service class is skipped during instantiation
It is not skipped. It's just the order of initialization that causes your problem.
Member fields are initialized first, before any constructor's code is run. Thus when the initializer of controller
is called, an exception is thrown because _configStream
is null. See this Q&A for further information.
Side note: In addition, it is a very bad idea to have the _configStream
field declared static
and at the same time initialize it from the constructor every time an instance is created.
Upvotes: 1