I have an IIS hosted app which takes an id from query string and instantiates user object like so. In AppHost.Configure I register UserService in IoC like so
container.Register(x => new UserService(x.Resolve<IDataContext>()).GetUser()).ReusedWithin(ReuseScope.Request);
My UserService (this is not a ServiceStack service, just an internal helper) looks like
public class UserService
{
public UserService(IDataContext dataContext)
{
_dataContext = dataContext;
}
public User GetUser()
{
var uid = HttpContext.Current.Request.QueryString["$id$"];
//snip
}
//snip
}
I want to change this to a self hosted app and therefore I don't have access to HttpContext any more. I have looked at HttpListenerContext but nothing seems to be populated when my class is being injected.
Can anyone shed any light on how to pass param from query string to this class?
You can't access any dependencies in your constructor and every ServiceStack action requires a Request DTO see the New API wiki for more details.
In your Service actions you can simply access the base.Request and base.Response when you need them e.g:
public class MyService : Service
{
public UserService UserService { get; set; }
public User Get(MyRequest request)
{
var user = UserService.GetUser(base.Request);
//snip
}
//snip
}
Note: there is no singleton for HttpListenerContext for Self-Hosting, so you can't get access to the runtime HTTP Request from inside an IOC lambda.
Related
I'm learning ServiceStack, and from reading this page, a couple of things aren't clear to me.
So, considering this DTO pair:
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
And this service:
public class MyService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
Why is it the responsibility of Hello to specify the return-type using the marker interface IReturn<HelloResponse>?
It seems like this could be inferred from the return-type of MyService - except that it's conventional to use a return-type of object, which also requires type-casts in tests and client-code. Why?
And why are the Route attributes applied to the model Hello, rather than to the service MyService, where the request is actually handled?
It seems like both of these facts are more relevant to the service than to the model.
For one, a person reading the service declaration would more readily find the information pertaining to the service, instead of having to find it in the model.
For another, accepted HTTP methods are implicitly declared by the service via method-naming conventions - so it seems like the facts about service routing/dispatch are sort of scattered between two layers.
From that point of view, I was probably expecting something more along the lines of this:
// NON-VALID EXAMPLE
public class Hello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
public class MyService : Service
{
[Route("/hello")]
[Route("/hello/{Name}")]
public HelloResponse Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
What is the reason or the design thinking behind the conventions?
(Please don't take this as merely an attempt at critique - there's a lot of things I enjoy about this framework, and I am genuinely trying to understand the thinking behind these conventions.)
Why does ServiceStack burden the DTOs with routing concerns?
Note no routing concern burden is required at all in ServiceStack and all user-defined Routes are optional where all clients are able to call Services utilizing their automatic pre-defined routes.
Why is it the responsibility of Hello to specify the return-type using the marker interface IReturn?
It provides better typed access for client libraries like the generic C#/.NET Service Clients who are able to re-use the existing SericeModel DTOs to enable its optimal typed API without any code-gen, e.g:
var client = new JsonServiceClient(baseUrl);
var response = client.Get(new Hello { Name = "World" });
Or if you're not sharing DTOs it's also useful for Add ServiceStack Reference generated clients as well.
The return type on your Service implementation is meaningless in ServiceStack, i.e. has no behavioral difference, and would prevent the same Service implementation from returning the same Response DTO, or decorated with a custom HTTP Response, e.g:
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
//...
return new HttpResult(new HelloResponse { Result = $"Hello, {request.Name}!" }) {
//... custom
};
}
both return types adhere to the API's IReturn<HelloResponse> contract
It's only useful for calling inter-process Services using the older ResolveService method, but for inter-prcess requests it's recommended to use the Service Gateway instead which also utilizes the type IReturn<T> interface markers for its Typed APIs.
The routes are not an implementation detail, they're apart of your public Service Contract and should be annotated on your DTOs which are used to define your Service Contract.
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
Where they're used by the .NET ServiceStack Clients to send Service Client Requests.
var response = client.Get(new Hello { Name = "World" });
For another, accepted HTTP methods are implicitly declared by the service via method-naming conventions - so it seems like the facts about service routing/dispatch are sort of scattered between two layers.
Please see docs on Routing, the Route definition defines which methods the specific route is active on whilst the most appropriate Service implementation is invoked depending on the Request, e.g:
public object GetJson(Customers request) => ... // ONLY GET JSON Requests
public object Get(Customers request) => ... // All other GET Requests
public object Post(Customers request) => ... // ONLY POST Requests
public object Any(Customers request) => ... // ALL other Requests
What is the reason or the design thinking behind the conventions?
A lot of these issues is trying to blur the explicit typed Service Contract of your APIs and its concrete implementation, in ServiceStack these are distinct explicit concepts where all the information about your public Service Contract should be maintained in your implementation-free ServiceModel project.
Please read the Background Concepts docs to familiarize yourself with ServiceStack's purpose and goals.
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.
I am currently working on a DDD-based application using Unity IOC container and need a way to pass my custom Principal object to the repository and service layers that would allow for unit testing. How should this be done? My current thoughts are to create a property on the service and repository classes of type IPrincipal. Then use Unity on Application_Start to set and pass in the Principal.
For one, am I on the right track in my thinking?
Two, if not at application_start, which seems like that is not the right place since I need a person to login first before the injections occur, where should this occur?
Three, for Unity, what should the container.RegisterType look like for getting the Principal from Thread.CurrentPrincipal or HttpContext.Current.User?
You can have a PrincipalDto class that will contain the relevant IPrincipal properties you need to use in your Service layer and map the values from the IPrincipal to the PrincipalDto. This way you do not need to include the reference assembly of IPrincipal to the other layers.
Below is an example that uses auto mapping.
public class PrincipalDto
{
public UserId { get; set; }
public Username { get; set; }
public RoleId { get; set; }
}
public class SomeService
{
public void SomeServiceMethod(PrincipalDto principal)
{
// do work here
}
}
public class SomeConsumer()
{
public void SomeConsumerMethod()
{
// where User is the IPrincipal object instance
var principal = Mapper.Map<PrincipalDto>(User);
var service = new Service();
service.SomeServiceMethod(principal);
}
}
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.
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.