Search code examples
servicestackormlite-servicestack

How to ensure our business-service is using the same db connection as the servicestack-service


We do have a few business services, which require an IDBConnection. It's quite important that these services do use the same dbconnection as the 'normal' Service-Stack service, so we do have atomic transactions.

our current solution for this problem is, to instantiate the business service in the servicestack-service constructor (using the IDbConnection that servicestack provides)

        private readonly ITaskService _taskService;

        public RegistrationService(IEmailService emailService, ITextProvider textProvider)
        {
            this._taskService = new TaskService(Db);
        }

However, I feel like this is not very 'smart' and there might be a way better solution which I'm overlooking right now.

Would a better option be, to inject the DbFactory instead of the plain connection? If so, does DbFactory already solve this problem?

Best,
Daniel


Solution

  • If you need to use the same open Db connection as that of a ServiceStack Service you should pass it in from your Service, e.g:

    public class MyServices : Service
    {
        public IMyDep MyDep { get; set; }
    
        public object Any(MyRequest request)
        {
            MyDep.Method(Db);
        }
    }
    

    Alternatively you can override GetDbConnection() in your AppHost to have it return the same db connection for that request, e.g:

    public override IDbConnection GetDbConnection(IRequest req = null)
    {
        if (req != null)
        {
            if (req.Items.TryGetValue("RequestDb", out var oDb) && oDb is IDbConnection db)
                return db;
            db = base.GetDbConnection(req);
            req.Items["RequestDb"] = db;
            return db;
        }
        return base.GetDbConnection(req);
    }
    

    That in your dependencies can access from AppHost.GetDbConnection(), e.g:

    public class MyDep : IMyDep 
    {
        private IDbConnection db;
        public virtual IDbConnection Db => db ?? (db = HostContext.AppHost.GetDbConnection(Request));
    
        public object Method()
        {
            var row = Db.Select<Table>();
        }
    }