Accessing IDbConnection from inside another auto-wired object

I’m writing a custom IValidator for incoming requests and am auto-wiring it as a singleton in AppHost like this…

container.RegisterAutoWiredAs<Validator, IValidator>().ReusedWithin(ReuseScope.Container);

One of my validations needs to first check an order’s current status from the DB before allowing an update. As such, I need access to a IDbConnection inside my validator. Since the IDbConnectionFactory is also a singleton, I have it working like this below. However, I wanted to see if this was the best way or if there was another way that’s more “proper”. Thoughts?

public interface IValidator
{
    Task<ValidationResult> ValidateAsync(OrderStatus request);
}

public class Validator : IValidator
{
    private IDbConnectionFactory dbFactory;
    private IDbConnection Db => (dbFactory ?? (dbFactory = AppHost.Instance.TryResolve<IDbConnectionFactory>())).OpenDbConnection();

    public async Task<ValidationResult> ValidateAsync(OrderStatus request)
    {
        var result = new ValidationResult();
        try
        {
            // Ensure order is in a state that *can* be updated
            var order = await Db.SelectOrderDetails(request.id);
            if (order == null)
                throw new ApiException(ErrorCode.ValidationError, "Order not found");
            if (order.IsCancelled)
                throw new ApiException(ErrorCode.ValidationError, "Order cancelled");

            result.IsValid = true;
        }
        catch (Exception e)
        {
            var apiException = e as ApiException;
            result.ErrorCode = apiException?.ErrorCode ?? ErrorCode.Unknown;
            result.Exception = apiException ?? e;
        }

        return result;
    }
}

Singleton is the default scope so you should just register it with:

container.RegisterAutoWiredAs<Validator, IValidator>();

Note you’re not using ServiceStack’s Validation here which needs to inherit from AbstractValidator<T>.

Don’t hold a reference to an open IDbConnection, you should fetch and dispose it when needed, e.g:

public async Task<ValidationResult> ValidateAsync(OrderStatus request)
{
    using (var db = HostContext.TryResolve<IDbConnectionFactory>().Open())
    {
        //..
    }
}

Thanks. I’ll tidy up the connection like you suggested. Correct that I’m not using ServiceStack’s validation…I want validation errors to adhere to a custom response DTO that I have. Didn’t see a way to do that (at least not initially) with the FluentValidation plugin.