Reputation: 53
I have the following Situation: My Service needs to handle different Types of Tasks, each of them getting its own Service-class. There should be a REST-Path /tasks/ (GenericTasksService) to access all of them, and other specific paths like /tasks/specifictask/.
public class Task
{
public string taskId { get;}
}
public class SpecificTask : Task
{
public string specificProperty { get; set; }
}
My idea was to register the specific Services with the GenericTasksService like this:
public class GenericTasksService : Service
{
private static List<ITaskService> taskServices = new List<ITaskService>();
public static void RegisterTaskService(ITaskService ts) { this.taskServices.Add(ts);}
public List<Task> Get(GetAllTasks gat)
{
List<Task> tasks = new List<Task>();
foreach(ITaskService ts in this.taskServices)
tasks.Add(ts.GetAllTasks());
return tasks;
}
}
public class SpecificTaskService : ITaskService
{
//from ITaskService
List<Task> GetAllTasks()
{
//access Repository and return the List
}
//SpecificTask-implementation would follow here
}
I then wanted to register my services in AppHost.Configure by calling
GenericTasksService.RegisterTaskService(new SpecificTaskService());
The problem with this is afaik, that the request context is not set by ServiceStack and so I don't have access to the session. (it is null)
Another option could be to use ResolveService<T> in the GenericTaskService, but I don't know how to do this without knowing the concrete types.
I also tried using AppHostBase.ResolveService<T>(HttpContext httpcx) when registering my TaskServices in AppHostBase.Configure, but at that moment I don't know where to get the RequestContext.
It is my first post at stackoverflow, I hope I did not overlook some conventions. ;) Thanks in advance for your help or suggestions.
Steffen
Upvotes: 2
Views: 321
Reputation: 53
I helped myself by registering types instead of instances like this:
public static void RegisterTaskServiceType(System.Type t)
{
Type iface = t.GetInterface("itaskservice",true);
if (iface == null)
throw new ArgumentException("Type-Argument needs to implement ITaskService.");
else if (taskServiceTypes.Contains(t))
throw new InvalidOperationException(string.Format("Type {0} is already registered.",t.FullName));
else
taskServiceTypes.Add(t);
}
In any of my Get-Methods I now resolve the services - if not already done - by using reflection to call the ResolveService<T>-method.
private void ResolveTaskServices()
{
if (!servicesResolved)
{
foreach (Type t in taskServiceTypes)
{
//Resolve Service via Reflection and add it to the List of Services
MethodInfo MethodObj = typeof(TasksService).GetMethod("ResolveService");
MethodInfo GenericMethodObj = MethodObj.MakeGenericMethod(t);
taskServices.Add((ITaskService)GenericMethodObj.Invoke(this, new object[] { }));
}
servicesResolved = true;
}
}
I need to implement a few more checks (Type also needs to implement ServiceStack.ServiceInterface.Service) but at least it works.
Upvotes: 1