What do you think about this way to make logging available across the application without passing log
object around? Let’s say we have something which allows us to write things this way:
class Program { static void Main(string[] args) { using (new Log("c:\\a.txt")) AsyncContext.Run(() => MainAsync()); } static async Task MainAsync() { Log.Write("a1"); // Writes to a.txt await Task.Delay(1000); Log.Write("a2"); // Writes to a.txt using (new Log("c:\\b.txt")) await F(); Log.Write("a3"); // Writes to a.txt } static async Task F() { Log.Write("b1"); // Writes to b.txt } }
Here is the Log
library code:
class Log : Ambient<Log>
{
public static void Write(string line) =>
Current?.WriteCore(line);
public Log(string fileName)
{
FileName = fileName;
}
void WriteCore(string line) => File.AppendAllText(FileName, line);
string FileName { get; }
}
Where Ambient<T>
is defined as:
class Ambient<T> : IDisposable where T : Ambient<T>
{
static readonly string Id = typeof(T).FullName;
protected static T Current
{
get { return (T)CallContext.LogicalGetData(Id); }
set { CallContext.LogicalSetData(Id, value); }
}
protected Ambient()
{
Previous = Current;
Current = (T)this;
}
public void Dispose() => Current = Previous;
T Previous { get; }
}
Theoretically, per-request instance of Log
could come from IoC with all the dependencies injected while taking into account ASP.NET applications.
CallContext
for the first time and I wonder why such a useful concept is put inside theRemoting
namespace and not directly underSystem
:-| one could think it's only for remoting... \$\endgroup\$