Ted
Ted

Reputation: 20184

ServiceStack: Accessing the IRequest in the Service returns null

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.

Upvotes: 1

Views: 240

Answers (1)

mythz
mythz

Reputation: 143319

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.

Upvotes: 1

Related Questions