简体   繁体   中英

Why does a C# class which inherits from ServiceBase skip its derived class constructor?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM