AppHostBase vs AppSelfHostBase

Most of the StackOverflow posts about how implementing very custom Validation logic in AbstractValidators (that access the database, check properties, check access), is frowned upon.

So I’ve implemented a custom IBusinessRuleValidator pipeline using SimpleInjectors container.RegisterCollection(typeof(IBusinessRuleValidator<>)…).

This all works great when hitting play and calling services with the /swagger-ui. I have a custom, Internal only ValidationService:

[Restrict(RequestAttributes.None)]
    public class ValidationService : Service
    {
        public void Validate<T>(T entity)
        {
            var validators = TryResolve<IEnumerable<BusinessRuleValidator<T>>>().ToList();

            // These will be the basic things every validator needs
            // And we don't want to have to inject these into every single validators constructor
            foreach (var validator in validators)
            {
                validator.User = SessionAs<CustomAuthUserSession>();
                validator.AuthRepository = AuthRepository;
                validator.DbFactory = ResolveService<IDbConnectionFactory>();
            }

            var errors = validators.SelectMany(x => x.Validate(entity)).ToList();

            if (errors.Any())
            {
                throw new BusinessRuleException(errors);
            }
        }
    }

But my first test fails at the validator.User = SessionAs(); line of code with the following error:

Message: System.NotImplementedException : This AppHost does not support accessing the current Request via a Singleton

In which the top lines of the stack trace are:

HostContext.GetCurrentRequest()
SessionFeature/GetOrCreateSession[T](ICacheClient cache, IRequest httpRequest, IResponse httpResponse)

Am I misunderstanding or misusing something here?

The Session requires the IRequest context and only host which supports getting access to the current IRequest without passing it in is ASP.NET Framework Apps via the HttpContext.Current. Singleton. I’m not sure where the cause of this exact exception is, because the SessionAs<T> in a Service does have access to the IRequest context so you must somehow me trying to access it outside the context of a Request.

With .NET Core Apps you can register HttpContextAccessor but it incurs a perf hit:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

Otherwise the APIs that require an IRequest have an overload to pass it in, which is needed in all Hosts where the current Request is not available via a singleton. As validators inherit AbstractValidator<T> they’re also injected with Request property. I’m assuming your custom implementation tries to make use of a dependency that requires the IRequest which is only available at runtime.

Not sure why the title of this question is titled AppHostBase vs AppSelfHostBase but AppSelfHostBase should only be used for self-host HttpListener Apps or for Unit tests where you want to create cross-platform integration tests. Otherwise for classic ASP.NET Apps or .NET Core Apps use AppHostBase.

This is for tests, I figured out a solution, although I’m not sure why it works.

When my ValidationService is just a public property (and thus injected upon the dependent services wire-up), it does not contain the IRequest and IResponse object (they are both null)

When I TryResolve it in the dependent service (var validationService = TryResolve() the IRequest and IResponse are populated and all is well.