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;
}
}