在MVC5中使用Autofac的Hangfire。 IoC使用DbContext注入任务

时间:2017-06-20 07:27:30

标签: asp.net-mvc entity-framework unity-container autofac hangfire

我确信之前已经出现,但经过我所有的搜索后,我找不到解决方案。

使用Unity的MVC5应用程序,我已经配置了一个简单的UnitOfWork,其中注入了DbContext并集成了OWIN(http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/)一切运行良好。

我刚刚添加了Hangfire,并希望将我的DbContext注入后台任务,类似于UnitOfWork类,看起来很简单。

通过其界面支持任务,安装了hangfire,并且根据我使用Autofac和Autofac.Mvc5看到的样本。第一次剪切我用一个空的构造函数运行它都工作正常。现在将DbContext添加到构造函数中并删除空构造函数并敲击...

每次HangFire触发任务时,我都会在"状态"中获得以下异常。 HangFire表:

@ApiOperation(value = "export",
        notes = "Export Report as a CSV")
@ApiResponses(value = {
        @ApiResponse(code = 400, message = "Bad Request"),
        @ApiResponse(code = 404, message = "Not Found"),
        @ApiResponse(code = 500, message = "Internal Server Error") })
@RequestMapping(method = RequestMethod.POST, value = "/export", produces = "text/csv")
public ResponseEntity export( @RequestBody SearchCriteria criteria )
{

    SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMddHHmm" );
    SAStatsManager saStatsManager = new SAStatsManager();
    InputStreamResource inputStreamResource;
    InputStream inputStream;
    byte[] byteArray = new byte[0];
    HttpHeaders httpHeaders = new HttpHeaders();

    try
    {
        inputStreamResource = saStatsManager.export( criteria );

        if ( inputStreamResource == null )
        {
            return new ResponseEntity( "Error in exporting report!!! ", HttpStatus.INTERNAL_SERVER_ERROR );
        }
        httpHeaders.set( HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + REPORT_NAME + criteria.getProductCombination() + "_" + sdf.format( new Date() ) + ".csv" );

        //convert inputStream to bytes
        inputStream = inputStreamResource.getInputStream();
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];

        while ( ( nRead = inputStream.read( data, 0, data.length ) ) != -1 )
        {
            buffer.write( data, 0, nRead );
        }

        buffer.flush();
        byteArray = buffer.toByteArray();

        httpHeaders.setContentLength( byteArray.length );

        return new ResponseEntity( byteArray, httpHeaders, HttpStatus.OK );
    }
    catch ( IOException e )
    {
        e.printStackTrace();
        return new ResponseEntity( e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR );
    }

}

我的配置如下:

UnityConfig.cs

    {"FailedAt":"2017-06-20T03:48:25.4862236Z","ExceptionType":"Autofac.Core.DependencyResolutionException","ExceptionMessage":"An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = EmailProcess (ReflectionActivator), Services = [[AppName].Tasks.EmailProcess], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type '[AppName].Tasks.EmailProcess' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Data.Entity.DbContext db' of constructor 'Void .ctor(System.Data.Entity.DbContext)'. (See inner exception for details.)","ExceptionDetails":"Autofac.Core.DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = EmailProcess (ReflectionActivator), Services = [[AppName].Tasks.EmailProcess], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type '[AppName].Tasks.EmailProcess' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Data.Entity.DbContext db' of constructor 'Void .ctor(System.Data.Entity.DbContext)'. (See inner exception for details.) ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type '[AppName].Tasks.EmailProcess' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Data.Entity.DbContext db' of constructor 'Void .ctor(System.Data.Entity.DbContext)'.
   at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   --- End of inner exception stack trace ---
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
   at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType)
   at Hangfire.AutofacJobActivator.AutofacScope.Resolve(Type type)
   at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)
   at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.<PerformJobWithFilters>b__0()
   at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)
   at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_1.<PerformJobWithFilters>b__2()
   at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)
   at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)
   at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)"}

Startup.cs

public class UnityConfig
{
    #region Unity Container
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }
    #endregion

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<DbContext, ApplicationDbContext>(new PerRequestLifetimeManager());
        container.RegisterType<ApplicationSignInManager>(); 
        container.RegisterType<ApplicationUserManager>(); 
        container.RegisterType<IAuthenticationManager>(new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
        container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(typeof(ApplicationDbContext)));

        container.RegisterType<IUnitOfWork, UnitOfWork>(new PerRequestLifetimeManager());
    }

后台任务

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);

        GlobalConfiguration.Configuration.UseSqlServerStorage("TaskEngine");
        var builder = new ContainerBuilder();
        builder.RegisterType<EmailProcess>();
        GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build());

        app.UseHangfireDashboard();
        app.UseHangfireServer();

        // point task engine toi email processing
        IEmailProcess emailProcess = DependencyResolver.Current.GetService<EmailProcess>();
        RecurringJob.AddOrUpdate(() => emailProcess.ProcessEmailQueue(), Cron.MinuteInterval(1));
    }
}

对于如何解决这个问题的任何想法都将非常感激。

0 个答案:

没有答案