Link Search Menu Expand Document

Tracing


This is a feature that would allow you to log, audit and debug the command execution context (i.e.: SQL Statement, Parameters, Elapsed Time) via TraceLog class. It also allows you to cancel the existing execution before even the actual execution via CancellableTraceLog class.

A corresponding method in the trace class will be hit by the debugger when you call any of the connection/repository extended methods, only if the trace object is passed or injected.

To be more precise, if you call the Insert operation, the BeforeInsert() and AfterInsert() method of the trace class will be invoked before and after the operation. There you can add the breakpoint to enable the debugging.

Create a Customize Trace Class

Create a class that implements the ITrace interface.

public class NorthwindTrace : ITrace
{
    public void AfterQuery(TraceLog log)
    {
        // Some implementations here
    }

    public void BeforeQuery(CancellableTraceLog log)
    {
        // Some implementations here
    }

    ...
}

You have to implement all the interface methods and manually handle each of them. You can leave it empty if you would like.

Using a Trace in a Connection

Simply pass the trace object when calling the operation.

using (var connection = new SqlConnection(connectionString))
{
    connection.Insert<Customer>(customer, trace: new NorthwindTrace());
}

Injecting the Trace in the Repository

Simply inject it in the contructor. Below is the sample code for BaseRepository class.

// Repository
public class CustomerRepository : BaseRepository<Customer, SqlConnection>
{
    public CustomerRepository(IOptions<AppSettings> settings)
        : base(settings.Value.ConnectionString, new NorthwindTrace())
    { }

    ...
}

// Use it like this (or via DI)
using (var repository = new CustomerRepository(settings))
{
    ...
}

And below is for DbRepository class.

// Repository
public class NorthwindRepository : DbRepository<SqlConnection>
{
    public NorthwindRepository(IOptions<AppSettings> settings)
        : base(settings.Value.ConnectionString, new NorthwindTrace())
    { }

    ...
}

// Use it like this (or via DI)
using (var repository = new NorthwindRepository(settings))
{
    ...
}

Or via direct class instantiation.

// Direct class instantiation of DbRepository
using (var repository = new DbRepository<SqlConnection>(settings.Value.ConnectionString, new NorthwindTrace()))
{
    ...
}

Dependency Injection Implementation

Create a custom interface that implements the ITrace interface.

public interface INorthwindTrace : ITrace
{
    // More custom methods
}

Then, implement it in the trace class.

public class NorthwindTrace : INorthwindTrace
{
    ...
}

Lastly, register in the services collection.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    // Registration
    services.AddSingleton<INorthwindTrace, NorthwindTrace>();
}

Below is the code on how to inject it in the repositories.

public class NorthwindRepository : DbRepository<SqlConnection>
{
    public NorthwindRepository(IOptions<AppSettings> settings,
        INorthwindTrace trace) // Injected
        : base(settings.Value.ConnectionString, trace)
    { }

    ...
}

Create a Trace Factory

If you do not prefer the dependency injection way, creating a simple trace factory class is a good way to abstract and ensure single instance of trace object is being created.

The code below ensures that only a single instance of trace object is being used all throughout the application.

public static class TraceFactory
{
    private readonly static object syncLock;
    private static ITrace trace = null;

    static TraceFactory()
    {
        syncLock = new object();
    }
    
    public static ITrace CreateTrace()
    {
        if (trace == null)
        {
            lock (syncLock)
            {
                if (trace == null)
                {
                    trace = new NorthwindRepository();
                }
            }
        }
        return trace;
    }
}

And use it in the IDbConnection object like below.

using (var connection = new SqlConnection(connectionString))
{
    connection.Insert<Customer>(customer, trace: TraceFactory.CreateTrace());
}

Or via repositories.

public class NorthwindRepository : DbRepository<SqlConnection>
{
    public NorthwindRepository(IOptions<AppSettings> settings)
        : base(settings.Value.ConnectionString, TraceFactory.CreateTrace())
    { }

    ...
}

You can as well visit our Trace reference implementation page for more details.