DbConnectionFactory returning closed connections

I’m currently trying to figure out an issue after some code refactoring where the DbConnectionFactory is returning a valid IDbConnection but in closed state.

I have a service class with my Get endpoint (SearchService). The ctor parameters are correctly injected when the service is called. One of these is a class that itself has an injected IDbConnectionFactory. (PriceManager)

The endpoint function makes a call into the object which in turn creates an IDbConnection to make some db calls. It is also IDisposible.

When I start the API in debug mode, I see PriceManager being instantiated (which is a bit strange as it’s not used anywhere else). When I then call the endpoint, I see the SearchService get instantiated with another PriceManager as I would expect.

The endpoint code runs fine, calls the PriceManager function, returns and I see the PriceManager.Dispose getting called (which closes the IDbConnection).

However, here’s where things go wrong. When I call that endpoint a second time, SearchService and PriceManager are instantiated again, but when the code runs calling PriceManager function, the DbConnectionFactory injected into it returns an IDbConnection that is closed, causing the query to throw an exception. Furthermore, the Dispose function of PriceManager gets called at a point before this. If I remove the dispose of the IDbConnection the query runs fine.

I’m confused as to what’s going on here and if there is something in how SS instantiates and disposes of services that I’m missing.

Here are some dummied down versions of the classes.

[ConnectionInfo(NamedConnection = OrmliteDatabaseSettings.ConnectionName)]
[HmacOrCredentialsAuthRequired]
public sealed class SearchService : Service {
    public SearchService(IPricingManager pricingmanager) {
        this.pricingManager = pricingmanager;    
    }

    public object Get(SearchRequest request) {
            return pricingManager.GetPricing(request);
    }
}

public class PricingManager: IPricingManager {

    private readonly IDbConnectionFactory dbConnectionFactory;
    private readonly string connectionName = OrmliteDatabaseSettings.ConnectionName;
    private IDbConnection db;

    public PricingManager(IDbConnectionFactory dbFactory)
    {
         this.dbConnectionFactory = dbConnectionFactory;
    }

    public IDbConnection Db => db ?? (db = dbConnectionFactory.OpenDbConnection(connectionName));

    public object GetPricing(SearchRequest request)
    {
         var items = Db.Select(Db.From<table>());
         // do some processing
         return items;
    }
    public void Dispose()
    {
        db?.Dispose();
    }
}

The DbConnectionFactory is registered as a SingleInstance in IOC (using autofac) and PricingManager is registered per lifetimescope (new instance for every usage).

I don’t see how the IDbConnectionFactory could be returning a closed db connection, I suspect an issue with your IOC lifetimes.

Instead of retrieving IPricingManager from the IOC, does the issue still exist if you’re passing in a new instance of IPricingManager?

Yeah, I don’t disagree that it’s probably something with IOC, but wanted to ask in case my expectations were wrong.

I’ve done a lot of refactoring of code and it appears to be working now. I can’t say for sure what it was, but I have a strong suspicion now that it was due to registration of that particular class being done in the apphost via the default servicestack IOC container. I suspect the registration scope was wrong. Removing it from there as part of the refactoring may have cleared it up.

Thanks.

1 Like