servicestackormlite-servicestackminiprofiler

How to extend ServiceStack IDbConnectionFactory and MiniProfiler


Given the following code for my connection factory:

public interface IDbFrontEndConnectionFactory : IDbConnectionFactory
{

}

public class FrontEndDbFactory : IDbFrontEndConnectionFactory
{
    private readonly IAppSettings _settings;

    private readonly IDbConnectionFactory _dbFactory;

    public Func<IDbConnection, IDbConnection> ConnectionFilter { get; set; }

    public FrontEndDbFactory(IDbConnectionFactory dbFactory, IAppSettings settings)
    {
        _dbFactory = dbFactory;
        _settings = settings;
        ConnectionFilter = (Func<IDbConnection, IDbConnection>)(x => x);
    }

    public IDbConnection OpenDbConnection()
    {
        var tenantId = Tenant.GetTenant();
        return OpenTenant(tenantId);
    }

    public IDbConnection OpenTenant(string tenantId = null)
    {
        return tenantId != null
            ? new OrmLiteConnectionFactory(_settings.GetString("TenantId{0}:{1}".Fmt(tenantId, "Frontend"))).OpenDbConnection()
            : _dbFactory.OpenDbConnection();
    }

    public IDbConnection CreateDbConnection()
    {
        return _dbFactory.CreateDbConnection();
    }
}

IoC registration

IDbFrontEndConnectionFactory feFactory = new FrontEndDbFactory(masterDbFactory, fileSettings)
{
    ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
};
container.Register(feFactory);

Global.asax

protected void Application_Start(object sender, EventArgs e)
{
    LogManager.LogFactory = new NLogFactory();
    new AppHost().Init();
}

protected void Application_BeginRequest(object src, EventArgs e)
{
    if (Request.IsLocal)
        Profiler.Start();
}
protected void Application_EndRequest(object src, EventArgs e)
{
    Profiler.Stop();
}

The Repository:

public partial class CampaignRepository : ICampaignRepository
{
    readonly ILog _log = LogManager.GetLogger(typeof(CampaignRepository));

    private readonly IDbFrontEndConnectionFactory _connectionFactory;

    public CampaignRepository(IDbFrontEndConnectionFactory connectionFactory)
    {
        _connectionFactory = connectionFactory;
    }
}

The IoC registration of my repository

container.Register<ICampaignRepository>(c => new CampaignRepository(c.Resolve<IDbFrontEndConnectionFactory>()));

The Service method when I'm inspecting the profiler

public CampaignViewModel Get(GetCampaign request)
{
    if (request == null) throw new ArgumentNullException("request");
    var profiler = Profiler.Current;
    using (profiler.Step("Campaign Service Get"))
    {
        try
        {
            var vm = CampaignRepository.GetCampaignInfo(request.Id).ToViewModel();
            if (vm.Campaign != null) return vm;
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            return null;
        }
        catch (Exception exception)
        {
            _log.Error(request.ToJson(), exception);
            throw;
        }            
    }
}

I was expecting the profiler to show the sql timings, but that's not the case, the connection is not being profiled.

Is there something else that needs to be enabled or corrected for this to work?

Thank you, Stephen


Solution

  • To enable SQL Profiling in MiniProfiler you need to register the OrmLiteConnectionFactory to use MiniProfilers ProfiledDbConnection, e.g:

    Container.Register<IDbConnectionFactory>(c =>
        new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider) {
            ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
        });