0

I want to add Debug and Trace to a class that I've created. However, I don't know where in my code to initialize a Trace Listener.

Here is the code I want to add to my static class:

Trace.Listeners.Add(
    new TextWriterTraceListener(
       File.CreateText("log.txt")
    )
);
Trace.AutoFlush = true;

Here is the class to which I want to add the Trace Listener:

using System;
using System.Diagnostics;
using System.IO;


namespace Example.Shared
{
    public static class ExampleClass
    {
        public static string SaySomething()
        {
            Trace.WriteLine($"I'm gonna say something");
            return "Something";
        }

        // etc.
    }
}

Apart from this class, I have only created some unit tests using Xunit. I have not yet created the application that will use this class.

This is what the unit test code looks like:

using Example.Shared;
using Xunit;

namespace ClassLibTests
{
    public class ExampleClassTests
    {
        [Fact]
        public void TestSaySomething()
        {
            string expected = "Something";
            string actual = ExampleClass.SaySomething();

            Assert.Equal(expected, actual);
        }
        // etc.
    }
}

I execute the above tests at the command line with the command dotnet test.

Fadi Hania
  • 705
  • 4
  • 11
  • Tracing has nothing to do with a specific IDE. Do you have the symbol TRACE defined in your build? See the first comment here https://stackoverflow.com/a/5931711/141172 – Eric J. Aug 18 '22 at 18:22
  • Very unclear what you are asking about. Code in the question clearly shows what needs to be done to log traces... Are you asking "how to configure logging in my app so traces show up in the console"? – Alexei Levenkov Aug 18 '22 at 18:25
  • I edited my question. Hope it makes more sense now. Thanks. – RedRum0503 Aug 18 '22 at 20:17
  • Normally you would do that from the program's main entry point logic, not from within a specific class. – 500 - Internal Server Error Aug 18 '22 at 20:18
  • Thanks for the update - it now clear what you want. I'm 100% with @500-InternalServerError - this is at least unusual (also more like very bad) idea. Indeed you *can't use* config file (which you probably wanted to say in your update) as class libraries do not have one... You probably can find your answer by searching for something like "C# where to put class library initialization". – Alexei Levenkov Aug 18 '22 at 20:25
  • Thanks, @500-InternalServerError. The thing is, I've so far only created a class library (containing my one static class) and unit tests for same. I was hoping to be able to finish building and testing my class library before going on to build and test the application that will use the class library. Is this not possible? – RedRum0503 Aug 18 '22 at 20:25
  • This answers your question, you can use static constructor: https://stackoverflow.com/a/6721846/4518630 – Fadi Hania Aug 18 '22 at 20:37
  • Thank you, @FadiHania. I added a static constructor, initialized a Trace Listener there to log to a text file as well as set Trace.AutoFlush to true, and added some Trace and Debug.WriteLine(...) statements to my code but no log is being generated when I run my Xunit unit tests. Any idea what I could be doing wrong? – RedRum0503 Aug 18 '22 at 21:01
  • I've just tested that by calling the `SaySomething()` method in main after using static constructor for initialization, it's working fine and creating the log file. Need to provide more details about your Xunit test that is not working – Fadi Hania Aug 18 '22 at 21:28
  • @FadiHania Thanks for your efforts. I only have a class library and some unit tests so far (see my reply to @500-InternalServerError), so there is no Main method at this point. – RedRum0503 Aug 18 '22 at 21:40
  • I understand that in Xunit there's no main, that's why I asked you to provide more details about your tests. If you can share the code that would make it easier to reproduce the issue – Fadi Hania Aug 18 '22 at 21:44
  • Added xunit test code to the question. – RedRum0503 Aug 18 '22 at 22:01
  • Found it... the log file was sitting under \bin\Debug\net6.0... I did check this before, but didn't see it the first time I looked! Sorry. – RedRum0503 Aug 18 '22 at 22:07
  • That means that my comment to use a static constructor was correct :) – Fadi Hania Aug 18 '22 at 22:09
  • @FadiHania It was! And thank you very much for your assistance. If you move your comment to an answer, I will mark it as correct (I think that's something the answerer does, right? New to all of this). Thank you also to everyone for your assistance. It takes a village to raise a child... and to help the village idiot. – RedRum0503 Aug 18 '22 at 22:13

1 Answers1

0

In order to initialize any static class or static members of a class you can use static constructors. So, you can update your code as follow:

using System;
using System.Diagnostics;
using System.IO;

namespace Example.Shared;

public static class ExampleClass
{
    static ExampleClass()
    { 
        Trace.Listeners.Add(
            new TextWriterTraceListener(File.CreateText("log.txt"))
        );
        Trace.AutoFlush = true;
    }

    public static string SaySomething()
    {
        Trace.WriteLine($"I'm gonna say something");
        return "Something";
    }

    // etc.
}

For more details check: C# static class constructor https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

BTW, I've also updated code to use the newly introduced file scoped namespace. Less indentation. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/file-scoped-namespaces

Fadi Hania
  • 705
  • 4
  • 11
  • This is very bad suggestion: I'm not sure why you think recommending to new C# user to randomly re-configure tracing setting for an application (both being random and re-configuration itself are significant problems). I understand that it is what OP is as asking, but *good* answer on SO should explain known problems with the suggested approach... – Alexei Levenkov Aug 18 '22 at 23:49