Closed Coldplayer1995 closed 5 years ago
Sorry, I can't solve your problem directly but just throwing an idea out there. In our web application we use Hangfire within ASP.NET. But we found that running Hangfire on production web servers will get problematic and affect the HTTP response time. So we deploy out to five IIS instances and on two of them we start the hangfire server and we have our load balancer not send HTTP traffic to those two. We did this so we didn't have to maintain a separate queue processing server/app. Its a config setting on whether the app starts the hang-fire server piece. They all can queue up jobs.
the error saying about that there is no parameterless constructor.
This usually means you don't have a valid activator for your DI configured (and the default one can only make use of parameterless constructors).
When running Hangfire in a .NET Core web app, activator and logger are automatically set by AddHangfire()
extension method during startup. On the other hand, when you're configuring your console app from scratch, you're all alone there.
It is indeed a good idea to use a web app template for a console app. Even if you're not going to use any of the web features, you still would get a (Web)Host Builder, with DI, logging and other things already configured for you from the start.
But the problem here is like a Di container is configured In Web api project whereas there is no Di in console app is that good when I will add another Di In console app which will duplicate services from other projects.Or maybe there is something like cross Di over two projects
@Coldplayer1995 did you resolve the problem? If not please post here your actual exception and configuration code to see what's going wrong.
Ok I will try to add all the code which is responsible for server running(console app) and normal dashboard job in hangfire(.net core 2.1) Console app partial implementation:
public class RevolutService
{
private BackgroundJobServer _server;
public void Start()
{
_server = new BackgroundJobServer();
}
public void Stop()
{
_server.Dispose();
}
}
TOPSHELF:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
var config = builder.Build();
var connectionString = config.GetConnectionString("HangfireConnection");
GlobalConfiguration.Configuration.UseSqlServerStorage(connectionString);
HostFactory.Run(x =>
{
x.UseSerilog();
x.Service<RevolutService>(s =>
{
s.ConstructUsing(name => new RevolutService());
s.WhenStarted(rs => rs.Start());
s.WhenStopped(rs => rs.Stop());
});
x.RunAsLocalSystem();
});
Hangfire
RecurringJob.AddOrUpdate("1", () => _revolutService.Add(), Cron.Minutely);
Exception returned here:
public class RevolutService : IRevolutService
{
private readonly InGameContext _context;
public RevolutService(InGameContext context)
{
_context = context;
}
public void Add()
{
SampleTable sampleTable = new SampleTable()
{
DateTimeStamp = DateTime.Now
};
_context.SampleTables.Add(sampleTable);
_context.SaveChanges();
}
}
It may be that InGameContext is not populated by DI from some weird reason whereas for example IRevolutService is correctly populated in ValuesController. If the server is started in API app everything is working fine the separation of the server is causing issues. Sorry for code editing but apparently it doesn't work correctly from some unknown reason.
Yes, that's simply because Hangfire doesn't know which IoC container to use. Without this, it can't find what instance to use for InGameContext
. For example, if you are using Autofac container, you need to install Hangfire.Autofac
package first and then register it:
GlobalConfiguration.Configuration
.UseSqlServerStorage(connectionString)
.UseAutofacJobActivator(container);
I already have one Di container in. Net core application the question is whether should I add aoutofac and duplicate services is that will not have bad impact? Or somehow clone the Di from other project but that maybe problem with cross platform Di
You need to add dependency injection to your service as well, because the only thing it knows that it should somehow create an instance of the RevolutService instance. All the background jobs are serialized into string format (you can check your DB), and objects aren't passed by reference, because they span the bounds of a process.
RecurringJob.AddOrUpdate("1", () => _revolutService.Add(), Cron.Minutely);
// ^^^ this method call is identical to the following one:
RecurringJob.AddOrUpdate<RevolutService>("1", x => x.Add(), Cron.Minutely);
Hello, My problem is that I have decided to separate the hangfire between my .net core web API and console application. The console app is responsible only for starting the hangfire server and the problem which I have got is probably with DI. What is happening is there is a problem with injecting a normal SQL server the error saying about that there is no parameterless constructor. Everything is working fine when I am using just web API project and server there so I have got the app.RunHangfireserver. How would you solve that I was thinking about grabbing all the DI services from my, .net Core API project and reuse them in a console app? Any clues ?. Happy New Year :)