1

I'm trying to use a injected object (IMessageBus) inside a job in FluentScheduler.

My autofac setup looks like this:

var thisAssembly = Assembly.GetExecutingAssembly();
var umbracoAssembly = typeof(UmbracoApplication).Assembly;
var builder = new ContainerBuilder();

// Controllers
builder.RegisterControllers(thisAssembly);
builder.RegisterApiControllers(thisAssembly);

// Umbraco related stuff (http://issues.umbraco.org/issue/U4-4181)
builder.RegisterControllers(umbracoAssembly);
builder.RegisterApiControllers(umbracoAssembly);

builder.RegisterType<MessageBus>().As<IMessageBus>();

Container = builder.Build();

And i have a scheduled job that looks like this:

public class CourseAgentJob : IJob
{
    private IMessageBus _bus;

    public CourseAgentJob(IMessageBus bus)
    {
        _bus = bus;
    }

    public async void Execute()
    {
        ErrorLog.GetDefault(HttpContext.Current).Log(new Error(new Exception("Fire course agent")));
    }
}

When my job fires/is setup, i get following error:

System.AggregateException: One or more errors occurred. ---> System.MissingMethodException: No parameterless constructor defined for this object. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstanceT at FluentScheduler.JobFactory.FluentScheduler.IJobFactory.GetJobInstanceT in A:\GitHub\FluentScheduler\Library\JobFactory.cs:line 25 at FluentScheduler.JobManager.<>c__121.<GetJobAction>b__12_0() in A:\GitHub\FluentScheduler\Library\JobManager.cs:line 66 at System.Threading.Tasks.Task.Execute() --- End of inner exception stack trace --- at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at FluentScheduler.JobManager.<>c__DisplayClass43_0.<RunJob>b__0() in A:\GitHub\FluentScheduler\Library\JobManager.cs:line 447 at System.Threading.Tasks.Task.Execute() ---> (Inner Exception #0) System.MissingMethodException: No parameterless constructor defined for this object. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstance[T]() at FluentScheduler.JobFactory.FluentScheduler.IJobFactory.GetJobInstance[T]() in A:\GitHub\FluentScheduler\Library\JobFactory.cs:line 25 at FluentScheduler.JobManager.<>c__121.b__12_0() in A:\GitHub\FluentScheduler\Library\JobManager.cs:line 66 at System.Threading.Tasks.Task.Execute()<---

Which looks like it's not registered correctly? I haven't done a lot of DI/IoC before, so i'm a bit lost.

stuartd
  • 70,509
  • 14
  • 132
  • 163
Christian Bekker
  • 1,857
  • 4
  • 27
  • 43

2 Answers2

1

You need to set up FluentScheduler to use your DI container, as documented here:

FluentScheduler makes it easy to use your IoC tool of choice to create job instances. Simply implement IJobFactory.

An example using StructureMap:

using FluentScheduler;
using StructureMap;

public class StructureMapJobFactory : IJobFactory
{
    public IJob GetJobInstance<T>() where T : IJob
    {
        return ObjectFactory.Container.GetInstance<T>();
    }
}

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        // Schedule an IJob to run at an interval
        Schedule<MyJob>().ToRunNow().AndEvery(2).Seconds();
    }
} 

Register the new job factory with the JobManager:

protected void Application_Start()
{
    JobManager.JobFactory = new StructureMapJobFactory();
    JobManager.Initialize(new MyRegistry()); 
}
Community
  • 1
  • 1
stuartd
  • 70,509
  • 14
  • 132
  • 163
  • I tried setting it up with autofac, `return DependencyResolver.Current.GetService();`, but getting error: `System.InvalidOperationException: The request lifetime scope cannot be created because the HttpContext is not available.` – Christian Bekker Dec 13 '16 at 12:58
  • Have a look at [Autofac - The request lifetime scope cannot be created because the HttpContext is not available](http://stackoverflow.com/questions/21804857/autofac-the-request-lifetime-scope-cannot-be-created-because-the-httpcontext-i) – stuartd Dec 13 '16 at 13:00
0

Currently most better solution is:

Schedule(myDIContainer.Resolve<MyJob>()).ToRunEvery(1).Days().At(13, 55);

It's closed issue.

hirtus
  • 1