The constructor is not called

I can't figure out why I keep getting null ref on the filename when I clearly name this singleton and it has to call Logger () to set the filename variable:

public class Logger
{
private static Logger defaultLogger = null;
readonly string filename;

public static Logger DefaultLogger
{
    get
    {
        // Check for valid instance
        if (defaultLogger == null) 
            defaultLogger = new Logger();

        // Return instance
        return defaultLogger;
    }
}

private Logger()
{
    filename = ConfigurationManager.AppSettings["MyLogPath"];
}


    public string Filename
    {
        get { return this.filename; }
    }

    public void Write(EntryType type, string data)
    {
        lock (this)
        {
            using (StreamWriter writer = new StreamWriter(filename, true))
            {
            //do something
            }
        }
    }
}

      

This is how I call this class:

Logger.DefaultLogger.Write(EntryType.Error, e.ToString());

      

So, I get this error at runtime, stating that filename is null:

 Value cannot be null.
Parameter name: path
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: path

Source Error:

Line 49: 
Line 50: 
Line 51:        public string Filename
Line 52:        {
Line 53:            get { return this.filename; }

      

This was our original code (I didn't write this), same problem:

public class Logger
{
    public static Logger DefaultLogger = new Logger();

string filename;

    public Logger()
    {
    filename = ConfigurationManager.AppSettings["LogPath"];
    }

    public Logger(string filename)
    {
        this.filename = filename;
    }

    public string Filename
    {
        get { return this.filename; }
    }

    public void Write(LogEntryType type, string data)
    {
        lock ()
        {
            using (StreamWriter writer = new StreamWriter(filename, true))
            {
                ...
        }
    }
}

      

+2


source to share


6 answers


It's because

ConfigurationManager.AppSettings["MyLogPath"];

      

is null?

Make sure you have the file App.Config

(it takes the form yourexe.exe.config

in the bin folder). You App.Config should have the following lines:

<configuration>
   <appSettings>
      <add key="MyLogPath" value="C:\Simple.txt" />
   <appSettings>
</configuration>

      

Perhaps to check, you can temporarily set the filename to a well-known path ( filename=@"D:\C#\mytext.txt";

) and see if you get the error or not.

If I set the filename explicitly, then I will not get this error, OTOH, if I set



filename=ConfigurationManager.AppSettings["MyLogPath"];

      

then i get

System.ArgumentNullException: The value cannot be null. Parameter name: path to System.IO.StreamWriter..ctor (String path, Boolean append, Encoding encoding, Int32 bufferSize) when System.IO.StreamWriter..ctor (String path, Boolean append)

If I step through using the debugger, I see that it failed:

(StreamWriter writer = new StreamWriter(filename, true)) 

      

I don't know why your debugger won't hit the constructor. My debugger hit the constructor in both cases.

+6


source


Despite this, too much.

    private Logger()
    {
        filename = ConfigurationManager.AppSettings["MyLogPath"];
        throw new Exception("filename = "+filename);
    }

      



Is an exception being thrown?

+1


source


I will copy the code and replace

filename = ConfigurationManager.AppSettings["MyLogPath"];

      

from

filename = @"test.log";

      

And it works great. So your mistake is writing "MyLogPath"

or in app.config

.

+1


source


Static initializers are executed the first time the class definition is accessed, which in your case means they are executed before your private constructor.

0


source


You are using blocking, so you expect this to be called in a multithreaded script, but you are not syncing the DefaultLogger. Also, are you sure you are setting filename to something nonzero first?

0


source


Try assigning the Logger instance variable to a variable in your client code and getting the FileName to it. It might be mis-assigned.
Also, you need to have the filename as read-only if you only provide a get property?

0


source







All Articles