[英]Is there any better way using hangfire with structuremap on ASP.net core?
I'm using structuremap with hangfire on asp.net core, no error on application but hangfire not process queue/schedule task even though data already on database. 我在asp.net核心上使用了与hangfire的结构图,在应用程序上没有错误,但是即使数据已经在数据库上,也没有处理队列/调度任务。 Here my snippet configuration 这是我的代码段配置
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// setup automapper
var config = new AutoMapper.MapperConfiguration(cfg =>
{
cfg.AddProfile(new AutoMapperProfileConfiguration());
});
var mapper = config.CreateMapper();
services.AddSingleton(mapper);
// Bind settings parameter
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.Configure<RouteOptions>(options => options.LowercaseUrls = true);
services.AddDbContext<DefaultContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddHangfire(options =>
options.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc();
// ASP.NET use the StructureMap container to resolve its services.
return ConfigureIoC(services);
}
public IServiceProvider ConfigureIoC(IServiceCollection services)
{
var container = new Container();
GlobalConfiguration.Configuration.UseStructureMapActivator(container);
container.Configure(config =>
{
// Register stuff in container, using the StructureMap APIs...
config.Scan(_ =>
{
_.AssemblyContainingType(typeof(Startup));
_.WithDefaultConventions();
_.AddAllTypesOf<IApplicationService>();
_.ConnectImplementationsToTypesClosing(typeof(IOptions<>));
});
config.For<JobStorage>().Use(new SqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));
config.For<IJobFilterProvider>().Use(JobFilterProviders.Providers);
config.For<ILog>().Use(c => LoggerFactory.LoggerFor(c.ParentType)).AlwaysUnique();
XmlDocument log4netConfig = new XmlDocument();
log4netConfig.Load(File.OpenRead("log4net.config"));
var repo = LogManager.CreateRepository(
Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
//Populate the container using the service collection
config.Populate(services);
});
return container.GetInstance<IServiceProvider>();
}
Is there any better way using hangfire and structuremap on asp.net core? 有没有更好的方法在asp.net核心上使用hangfire和structuremap? Am I missing something so hangfire not working properly? 我错过了什么,所以hangfire不能正常工作?
My Hangfire structure map implementation 我的Hangfire结构图实现
using Hangfire;
using StructureMap;
namespace Lumochift.Helpers
{
/// <summary>
/// Bootstrapper Configuration Extensions for StructureMap.
/// </summary>
public static class StructureMapBootstrapperConfigurationExtensions
{
/// <summary>
/// Tells bootstrapper to use the specified StructureMap container as a global job activator.
/// </summary>
/// <param name="configuration">Bootstrapper Configuration</param>
/// <param name="container">StructureMap container that will be used to activate jobs</param>
public static void UseStructureMapActivator(this GlobalConfiguration configuration, IContainer container)
{
configuration.UseActivator(new StructureMapJobActivator(container));
}
}
}
using Hangfire;
using StructureMap;
using System;
namespace Lumochift.Helpers
{
public class StructureMapJobActivator : JobActivator
{
private readonly IContainer _container;
/// <summary>
/// Initializes a new instance of the <see cref="StructureMapJobActivator"/>
/// class with a given StructureMap container
/// </summary>
/// <param name="container">Container that will be used to create instances of classes during
/// the job activation process</param>
public StructureMapJobActivator(IContainer container)
{
if (container == null) throw new ArgumentNullException(nameof(container));
_container = container;
}
/// <inheritdoc />
public override object ActivateJob(Type jobType)
{
return _container.GetInstance(jobType)
}
/// <inheritdoc />
public override JobActivatorScope BeginScope(JobActivatorContext context)
{
return new StructureMapDependencyScope(_container.GetNestedContainer());
}
private class StructureMapDependencyScope : JobActivatorScope
{
private readonly IContainer _container;
public StructureMapDependencyScope(IContainer container)
{
_container = container;
}
public override object Resolve(Type type)
{
return _container.GetInstance(type);
}
public override void DisposeScope()
{
_container.Dispose();
}
}
}
}
Example hangfire call on controller 控制器上的示例hangfire调用
BackgroundJob.Enqueue<CobaService>((cb) => cb.GetCoba());
BackgroundJob.Schedule<CobaService>((cb) => cb.GetCoba(), TimeSpan.FromSeconds(5) );
You should use Hangfire.AspNetCore nuget package. 您应该使用Hangfire.AspNetCore nuget包。
It uses AspNetCoreJobActivator
as the default job activator, so you don't have to create your own. 它使用AspNetCoreJobActivator
作为默认作业激活器,因此您不必创建自己的作业激活器。
AspNetCoreJobActivator
uses IServiceScope.ServiceProvider.GetRequiredService(type)
method to resolve dependencies. AspNetCoreJobActivator
使用IServiceScope.ServiceProvider.GetRequiredService(type)
方法来解析依赖关系。 The same ServiceProvider, that you return from ConfigureServices
, with all the services configured by structuremap. 您从ConfigureServices
返回的相同ServiceProvider,其中包含由structuremap配置的所有服务。
You should return StructureMapDependencyScope
with nested container from BeginScope
: 您应该返回StructureMapDependencyScope
与嵌套容器BeginScope
:
public override JobActivatorScope BeginScope(JobActivatorContext context)
{
return new StructureMapDependencyScope(_container.GetNestedContainer());
}
Also, I would not mix container with Activator.CreateInstance
and just go with _container.GetInstance(jobType)
in ActivateJob
另外,我不会将容器与Activator.CreateInstance
混合使用,只需在ActivateJob
使用_container.GetInstance(jobType)
。
The main problem is not on implementation structure map with hangfire. 主要问题不在于使用hangfire的实现结构图。 at first though I think this is because SQL server version but after downgrade downgrade the problem still same. 起初虽然我认为这是因为SQL服务器版本但降级后降级问题仍然相同。 only queue but no job activated. 只有队列但没有激活任务。 After change the configuration setting I found the problem. 更改配置设置后,我发现了问题。
"DefaultConnection": "Server=127.0.0.1,1434;Database=db;User Id=sa;Password=pass;MultipleActiveResultSets=true"
this is the problem, I use port 1434
after I changed using without specified port or using port 1433 everything running normally. 这是问题,我在使用没有指定端口或使用端口1433正常运行的所有内容后使用端口1434
。 no job stuck on queue anymore. 再也没有工作卡在队列上了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.