-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Job execution not working in dynamically loaded assemblies #470
Comments
Hi @thnk2wn, I haven't tested this. But if it works in Quartz (however, it uses the same
Would you like to reduce the code to simplify testing? |
@odinserj Sorry about that. I've removed our internal packages from those projects. NLog is public on nuget but the other two are now removed in my sample repo |
I've been getting the same error. I'm using the same concept of @thnk2wn is using. |
Maybe implementing AssemblyResolve? |
I've done PR #486 to resolve this issue |
I have this problem, but I checked the latest code, and did not solve this problem, is there any way to solve |
Any progress in this? |
I'm also watching/waiting 👍 |
+1 |
Anyone has an awnser to this? |
This is also something that would be awesome for us. We also use a console application to host the job code but have had to keep releasing the console app each time we have a change :-(. So I too am looking for a solution to this one. |
Try to reproduce the issue using Hangfire 1.7.0-beta1 released yesterday – serialised type information doesn't contain assembly version anymore, may be new format will help. If not, I'll add the |
Thanks for your patience. Default type resolver in the new 1.7.0 version dynamically loads the required assemblies, so there will be no exceptions, when assembly is on disk, but not loaded into the application. Also, if type resolver was unable to load the assembly using its strong name, it will retry with a partial name, so there's less need in binding redirects. New version is already released, please see the upgrade guide: https://docs.hangfire.io/en/latest/upgrade-guides/upgrading-to-hangfire-1.7.html. |
This issue still remains in version 1.7.33. I am on .Net 6 and running a hosted service to execute jobs. Jobs are build as plugins and dropped to a plugin directory inside the hosted service with all it's dependancies. To properly load the plugins with it's dependancies I use https://github.com/natemcmaster/DotNetCorePlugins nuget. All dependencies get properly loaded to DI. However when the job gets executed it gives the same error Could not load file or assembly 'MyCompany.Services.Messaging, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified. May be Hangfire searches only it's parent folder and not sub folders for the assemblies? Since my plugins are in |
Hangfire doesn't store custom paths for such assemblies, but you can override the type resolver in the following way: TypeHelper.CurrentTypeResolver += typeName =>
{
if (typeName.Contains("MyCompany.Services.Messaging"))
{
// Load assembly from the specific place and use it to find the type
return Assembly.GetType(typeName);
}
return TypeHelper.DefaultTypeResolver(typeName);
}; |
Thanks, so the name I get to my custom resolver is something like below
Just to be sure that my AppDomain has the required types registered; I scanned AppDomain.CurrentDomain.GetAssemblies(), and printed AssemblyQualifiedName property. it shows below types are loaded
I also used;
to make it a bit simpler hoping this will also make it a bit easy to get the job done. This simplifed the type name without version, culture etc... as below.
Then, the quickly hacked type resolver code is below.
This resolver gets hit twice, one for MyCompany.Messaging.IMessageSender`1 and MyCompany.Messaging.Email.EMailMessage Since both of the above types are now in AppDomain, I return them and this throws two exceptions which I can't figure out the cause.
All of this works fine if I statically link my plugins to hangfire server project and we will have lot of different jobs and linking all of them to hangfire server project is not the right way to go I think. |
Ok, so got this to work. I will try to brief the issue so that someone else will find this helpful if they are also trying to use plugins with hangfire. Key points to note is that my jobs are in separate dlls and to load them properly with dependencies I use https://github.com/natemcmaster/DotNetCorePlugins The way it works, my custom resolver will not be able to locate the types properly. See Reflection. Therefore, my custom type resolver now looks like below;
Above will call a method in plugin loader like below. I cache the types in a dictionary to make it a bit efficient in subsequent calls.
Check the plugin library I use for more details. |
I have a Console App / Windows Service that uses a plugin style model which dynamically loads plugin assemblies (using MEF) containing code to schedule jobs in Hangfire as well as the jobs themselves.
At runtime I get the following error ("hidden" but visible via hangfire dashboard under recurring jobs):
Could not load file or assembly 'Cyrus.ClientMergeEmails, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
I can set breakpoints and see that assembly loaded, and see the job scheduled in Hangfire but the job class never gets created.
I can do the same style of dynamically loaded jobs in Quartz.net without issue. I can also do the same thing in Hangfire if I use static references instead of dynamically loading the assemblies.
I created this repo to demonstrate the issue: https://github.com/thnk2wn/WindowsServicePluginJobDiscovery
There are 3 proof of concepts here:
Should this work in Hangfire? Is there anything I can do to make it work?
The text was updated successfully, but these errors were encountered: