ServiceStack: Accessing the IRequest in the Service returns null - servicestack

I am using Servicestack. I have a base class for my Services, like so:
public abstract class ServiceHandlerBase : Service
and then some methods and properties in there of interest. I already have several methods that accesses the IRequest object, like:
protected AlfaOnline GetContactItem()
{
string deviceUUID = Request.Headers.Get(Constants.DEVICE_UUID); // <-- calling this method from constructor will give NullRef on Request here
string authToken = Request.Headers.Get(Constants.AUTH_TOKEN);
// do stuff
return existingContactItem;
}
which works well inside my service implementations, no problems there.
Now, I wanted to use this exact same method directly from the base class, calling it in the constructor:
public ServiceHandlerBase()
{
AlfaOnline ao = GetContactItem();
}
but I then get a NullReferenceException on the Request object as noted above.
When is the Request object ready to access and use? Because it's not null inside the service implementations.

You can't access any dependencies like IRequest in the constructor before they've been injected, they're only accessible after the Service class has been initialized like when your Service method is called.
You can use a Custom Service Runner to execute custom logic before any Service is Executed, e.g:
public class MyServiceRunner<T> : ServiceRunner<T>
{
public override void OnBeforeExecute(IRequest req, TRequest requestDto) {
// Called just before any Action is executed
}
}
And register it with ServiceStack in your AppHost with:
public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext ctx)
{
return new MyServiceRunner<TRequest>(this, ctx);
}
But if you just want to run some logic for a Service class you can now override OnBeforeExecute() in your base class, e.g:
public abstract class ServiceHandlerBase : Service
{
public override void OnBeforeExecute(object requestDto)
{
AlfaOnline ao = GetContactItem();
}
}
See ServiceFilterTests.cs for a working example.
If you're implementing IService instead of inheriting the Service base class you can implement IServiceBeforeFilter instead.
The new Service Filters is available from v5.4.1 that's now available on MyGet.

Related

Setting proper Unity Container configuration for resolving interface-class in decorator pattern

Given below are my different class declarations and how I am trying to setup unity container configuration to get a Interface to Concrete class implementation. The code currently throws either an stackoverflow exception or suggests that a interface cannot be constructed.
Please help me fix, either the class structure or the container configuration.
CodesController Class -
public class CodesController : ApiController
{
private readonly IUnitOfWorkAsync unitOfWork;
private readonly ICodeRepository repository;
public CodesController(IUnitOfWorkAsync unitOfWork, ICodeRepository codeRepository)
{
if (unitOfWork == null)
{
throw new ArgumentNullException("unitOfWork");
}
this.unitOfWork = unitOfWork;
this.repository = codeRepository;
}
//Other class level methods here
}
CodeRepository class -
public class CodeRepository : ICodeRepository
{
private readonly ICodeRepository codeRepository;
public CodeRepository(ICodeRepository repository)
{
this.codeRepository = repository;
}
public virtual async Task<IEnumerable<Code>> GetCodeAsync(string codeKey)
{ //Some implementation here}
}
ICodeRepository Interface -
public interface ICodeRepository : IRepositoryAsync<Code>
{
Task<IEnumerable<Code>> GetCodeAsync(string codeKey);
}
IRepositoryAsync Interface -
public interface IRepositoryAsync<TEntity> : IRepository<TEntity> where TEntity : class, IPersistenceHint
{
Task<bool> DeleteAsync(params object[] keyValues);
Task<bool> DeleteAsync(CancellationToken cancellationToken, params object[] keyValues);
Task<TEntity> FindAsync(params object[] keyValues);
Task<TEntity> FindAsync(CancellationToken cancellationToken, params object[] keyValues);
}
Unity Container Configuration-
container.RegisterType<IUnitOfWorkAsync, UnitOfWork>(
"test",
new TransientLifetimeManager(),
new InjectionConstructor(container.Resolve<IDataContextAsync>("test")));
container.RegisterType<ICodeRepository, CodeRepository>();
container.RegisterType<CodesController, CodesController>();
With this given configuration and class structure, based on my experimentation with container config, I get following exception -
JSON
exceptionMessage=An error occurred when trying to create a controller of type 'CodesController'. Make sure that the controller has a parameterless public constructor.
exceptionType=System.InvalidOperationException
innerException
exceptionMessage=Type '<Namespace>.Api.Controllers.CodesController' does not have a default constructor
stackTrace= at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
Please suggest, if anything is wrong here, so that I can fix the same. Already struggling many days on this.
You're injecting ICodeRepository to CodeRepository, which probably causes to stackoverflow exception, since it will keep generating ICodeRepositories. It will generate a recursive call. Somewhat like this one:
public class BaseFoo
{
public BaseFoo(BaseFoo foo){ }
}
public class Foo : BaseFoo
{
public Foo() : base(new Foo()) { }
}
And regarding the "does not have a default constructor"-exception, have you registered a DependencyResolver for Web API? See one of these questions for more detailed information how to do it:
Using Unity with Web Api 2 gives error does not have a default constructor
Unity.WebApi | Make sure that the controller has a parameterless public constructor
ASP.Net MVC 4 Web API controller dosn't work with Unity.WebApi
As a side note, you shouldn't have to register the CodesController in your unity registration.

ServiceStack.Funq.Quartz cannot instantiating type?

ServiceStack.Funq.Quartz Sample Code is
public class MyServices : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Hello, {0}!".Fmt(request.Name) };
}
}
public class HelloJob : IJob
{
private MyServices MyServices { get; set; }
public HelloJob(MyServices myServices)
{
MyServices = myServices;
}
public void Execute(IJobExecutionContext context)
{
var response = MyServices.Any(new ServiceModel.Hello
{
Name = "CodeRevver"
});
response.PrintDump();
}
}
The above is works fine. if I in the MyServices Class, removed the Any function, and comment the Execute inner code.
public class MyServices : Service
{
}
the quartz.net will get the error:
[Quartz.Core.ErrorLogger】 An error occurred instantiating job to be executed. job= 'JobGroup1.GetUserJob111' Problem instantiating type 'ServiceStackWithQuartz.HelloJob'
why the class must have public object Any(Hello request) function ?
Thanks for using the package – I had no idea that other people would find it useful.
So If I understand correctly, in your situation you have:
public class MyServices : Service
{
}
And you’re trying to resolve this Service via constructor injection, which is effectively doing a:
container.Resolve<MyServices>();
This will fail because of the way the ServiceStack Funq IoC works. You can’t resolve a ServiceStack Service that has nothing in it (you'd probably never want to either) – It has to at least have one service implementation, It doesn’t matter what the implementation is.
Also, if you want to improve ServiceStack.Funq.Quartz, feel free to contribute to the code base.
Edit: It's probably worth mentioning that you can inject a "Non-Service" class with your logic in it if you want. You can resolve other classes that aren't based off of ServiceStack.Service even if there's nothing in them.
Edit 2: Responding to your "Service wont dispose" problem. This is the same across ServiceStack and has nothing to do with your Quartz Job. If you call a:
container.Resolve<MyServices>().Any(new new ServiceModel.Hello { });
from AppHost for example, your service wont dispose by itself. If you want it to dispose you can wrap it in a using statement. e.g.
using (var service = MyServices)
{
var response = MyServices.Any(new ServiceModel.Hello { });
}
The using will ensure that your service will be disposed afterwards.
Alternatively you can add the interface "IDispose" on to your Quartz Job and implement a Dispose() method that will do a:
MyServices.Dispose();
This will be called after a job has executed.

Approach on mocking ServiceStack service being called by another ServiceStack service

Let's say we have a situation where a service would call other services in ServiceStack.
From reading around, this is how one would call another service:
public class CompanyService : Service
{
public SetupCompanyResponse Any(SetupCompany request)
{
var employeeService = base.ResolveService<EmployeeService>();
// Do something with employeeService
var response = employeeService.Any(new SetupEmployees());
return new SetupCompanyResponse { NumOfEmployeesCreated = response.Count };
}
}
Question: How do I mock EmployeeService if I'm unit-testing CompanyService?
Easiest way I could think of is to generate an IEmployeeService interface so that it's easily mockable. However I'm not sure if base.ResolveService<T> will be able to properly resolve and auto-wire a ServiceStack service, given its interface instead, like so:
var employeeService = base.ResolveService<IEmployeeService>();
Especially when we are registering services this way (which I assume is configuring the object resolution based on concrete class, and not the interface e.g IEmployeeService)
public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }
Update:
Apparently I'm able to somewhat achieve this simply by:
1) Registering the service interface with its implementation
public static void SetupServices(Container container)
{
container.RegisterAs<EmployeeService, IEmployeeService>();
}
2) Using the same exact code to resolve, except now I pass in the interface. The service is successfully resolved.
var employeeService = base.ResolveService<IEmployeeService>();
3) All I need to do now is to override the resolver, and the service dependency should be totally mockable.
Question: Is this also a valid approach? Why or why not?
ServiceStack's Service class resolves all its dependencies from an IResolver, defined by:
public interface IResolver
{
T TryResolve<T>();
}
This can be injected in ServiceStack's Service class in an number of ways as seen by the implementation:
public class Service : IService, IServiceBase, IDisposable
{
public static IResolver GlobalResolver { get; set; }
private IResolver resolver;
public virtual IResolver GetResolver()
{
return resolver ?? GlobalResolver;
}
public virtual Service SetResolver(IResolver resolver)
{
this.resolver = resolver;
return this;
}
public virtual T TryResolve<T>()
{
return this.GetResolver() == null
? default(T)
: this.GetResolver().TryResolve<T>();
}
...
}
Which you can use to control how Services resolve dependencies.
An easy way to unit test Services is to use a BasicAppHost as seen on the Testing wiki, i.e:
appHost = new BasicAppHost().Init();
var container = appHost.Container;
container.Register<IDbConnectionFactory>(
new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));
container.RegisterAutoWired<CompanyService>();
container.RegisterAutoWiredAs<StubEmployeeService, EmployeeService>();
Where StubEmployeeService is your stub implementation of EmployeeService, e.g:
public class StubEmployeeService : EmployeeService
{
public SetupEmployeesResponse Any(SetupEmployees request)
{
return new SetupEmployeesResponse { ... };
}
}
You can also register Services using any of the registration methods ServiceStack's IOC Supports if you prefer to use your own mocking library.

ServiceStack Access Ioc container within Custom CredentialsAuthProvider

I've extended the CredentialsAuthProvider provided by service-stack to allow me to authenticate against a Active-Directory instance. The AD access logic is encapsulated within a custom class called AdManager (see below)
e.g.:
public class AdCredentialsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService,
string userName,
string password)
{
IAdManager manager = new AdManager();
return manager.Authenticate(userName, password);
}
...
Question:
I was hoping I could register the AdManager using service-stacks built-in IoC "Funq.Container" within my extended "AppHostBase" and access it from within my custom CredentialsAuthProvider? I tried registering it but have not found a way of accessing the IoC (or my registered AdManager object) via the service-stack built in framework.
Am I missing something?
Thanks
You can access the IOC from within the AuthProvider with the supplied IServiceBase, e.g:
var addManager = authService.TryResolve<IAdManager>();
Anywhere else you can always resolve dependencies using the Singleton:
var addManager = HostContext.TryResolve<IAdManager>();
Otherwise if you know it's in an ASP.NET Web Host you also access it via your AppHost singleton:
var addManager = AppHostBase.Instance.Resolve<IAdManager>();
Service Stack uses property injection as well. I have used property injection when extending the Service class provided by Service stack.
public class MyService : Service
{
public MyService(IDb db)
{
//db constructor inject
}
public IValidator<MyData> MyDataValidator { get; set; }
public object Get(MyData request)
{
//MyDataValidator is property injected
}
}
I believe the same logic can be applied to the AuthProvider. But I havent tested it.

Catching exceptions with servicestack

We have been using ServiceStack for REST based services for a while now and so far it has been amazing.
All of our services have been written as:
public class MyRestService : RestService<RestServiceDto>
{
public override object OnGet(RestServiceDto request)
{
}
}
For each DTO we have Response equivalent object:
public class RestServiceDto
{
public ResponseStatus ResponseStatus {get;set;}
}
which handles all the exceptions should they get thrown.
What I noticed is if an exception is thrown in the OnGet() or OnPost() methods, then the http status description contains the name of the exception class where as if I threw a:
new HttpError(HttpStatus.NotFound, "Some Message");
then the http status description contains the text "Some Message".
Since some of the rest services are throwing exceptions and others are throwing new HttpError(), I was wondering if there was a way without changing all my REST services to catch any exceptions and throw a new HttpError()?
So for example, if the OnGet() method throws an exception, then catch it and throw a new HttpError()?
Using Old API - inherit a custom base class
As you're using the old API to handle exceptions generically you should provide a Custom Base class and override the HandleException method, e.g:
public class MyRestServiceBase<TRequest> : RestService<TRequest>
{
public override object HandleException(TRequest request, Exception ex)
{
...
return new HttpError(..);
}
}
Then to take advantage of the custom Error handling have all your services inherit your class instead, e.g:
public class MyRestService : MyRestServiceBase<RestServiceDto>
{
public override object OnGet(RestServiceDto request)
{
}
}
Using New API - use a ServiceRunner
Otherwise if you're using ServiceStack's improved New API then you don't need to have all services inherit a base class, instead you can just tell ServiceStack to use a custom runner in your AppHost by overriding CreateServiceRunner:
public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
ActionContext actionContext)
{
return new MyServiceRunner<TRequest>(this, actionContext);
}
Where MyServiceRunner is just a just custom class implementing the custom hooks you're interested in, e.g:
public class MyServiceRunner<T> : ServiceRunner<T> {
public override object HandleException(IRequestContext requestContext,
TRequest request, Exception ex) {
// Called whenever an exception is thrown in your Services Action
}
}

Resources