Continuing discussing the logging, let’s talk about LibLog. Unlike other logging libraries, LibLog targets just one specific scenario – logging within reusable libraries.

Why this scenario needs a specific treatment? There are two general logging approaches for the library developers: one is to choose a logging library and force all library consumers to use the same library, and another is to create a logging façade and ask the consuming application to create an adapter for the preferred logging library like NLog or Serilog. Obviously, both approaches are not very elegant, and LibLog provides a solution based on the optimized second approach.

LibLog consists from just one file which can be added to the project directly from the GitHub repository or using a corresponding NuGet package. In case of manual approach, LibLog.cs will require namespace editing (detailed instructions provided in the file header comments).

After that, LibLog’s entry point, LogProvider class, becomes available for use. By design it is only available for the assembly which contains LibLog.cs. If the library includes more than one assembly, InternalsVisibleToAttribute can be used to share the logging infrastructure across all the components of the library without exposing it to the consumers.

A simple usage scenario looks like this:

public class MyClass
    {
        private static readonly ILog Logger = LogProvider.For();

        public void DoSomething()
        {
            Logger.Trace("Method 'DoSomething' in progress");
        }
    }

That’s it, no the library is ready to automatically pick-up logger used by the consuming application. For example, if Serilog is the selected library, assigning Serilog’s Logger.Log will automatically connect all the moving parts together:

Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Verbose()
                .WriteTo.LiterateConsole()
                .CreateLogger();

            Log.Logger.Verbose("Starting...");

            var myClass = new MyClass();
            myClass.DoSomething();

            Log.Logger.Verbose("Finishing...");
            Console.ReadKey();

The result is

[21:09:18 APP] Starting...
[21:09:18 APP] Method 'DoSomething' in progress
[21:09:18 APP] Finishing... 

Everything described before just works when library targeting .NET Framework. In case of .NET Standard library (at least netstandard1.3) things are a bit more complicated. When LibLog is added to such library, compilation will fail and two modifications are required to fix it.

First, LIBLOG_PORTABLE conditional compilation symbol shall be defined in the project settings (don’t forget to define it in all used build configurations). Second, two missing NuGet packages shall be added - Microsoft.CSharp and System.Dynamic.Runtime. These modifications will fix the build and enable LibLog usage.

blog comments powered by Disqus