I have a MVC application that uses Unity as its IoC container and have multiple services defined in my application using the PerRequestLifetimeManager
.
container.RegisterType<IFileService, FileService>();
Everything works fine, except when I tried to roll my solution to automate tasks (like SharePoint TimerJobs), started in various intervals.
For that, I've defined a ServiceLocator
-Type class ContainerManager
in a separate project, that does essentially this:
public static object Resolve(string typeName)
{
var type = Type.GetType(typeName);
return Resolve(type);
}
public static object Resolve(Type type)
{
object result = DependencyResolver.Current.GetService(type);
return result;
}
public static T Resolve<T>() where T : class
{
object result = DependencyResolver.Current.GetService<T>();
return (T)result;
}
public static object Resolve(string typeName)
{
var type = Type.GetType(typeName);
return Resolve(type);
}
public static object Resolve(Type type)
{
object result = DependencyResolver.Current.GetService(type);
return result;
}
public static T Resolve<T>() where T : class
{
object result = DependencyResolver.Current.GetService<T>();
return (T)result;
}
And inside my "TaskManager" I do the following:
var unitOfWork = ContainerManager.Resolve<IFileService>();
Now this works when started manually (when originating from an HttpRequest). However, this does not work when started via my background thread.
I've tried calling unity directly (without my ServiceLocator), but then I'll get the exception: PerRequestLifetimeManager can only be used in the context of an HTTP request
That's how I create my tasks:
private ITask CreateTask()
{
ITask task = null;
if (IsEnabled)
{
var type = System.Type.GetType(Type);
if (type != null)
{
object instance = ContainerManager.Resolve(type);
if (instance == null)
{
// Not resolved
instance = ContainerManager.ResolveUnregistered(type);
}
task = instance as ITask;
}
}
return task;
}
What am I missing?