HangfireIO / Hangfire

An easy way to perform background job processing in .NET and .NET Core applications. No Windows Service or separate process required
https://www.hangfire.io
Other
9.35k stars 1.69k forks source link

System.TypeLoadException while installing Hangfire SQL objects #2276

Closed SoftCircuits closed 1 year ago

SoftCircuits commented 1 year ago

My console app is working fine on my local machine. But when I upload it to the server, I get an exception.

info: Hangfire.SqlServer.SqlServerObjectsInstaller[0]
      Start installing Hangfire SQL objects...
Unhandled exception. System.TypeLoadException
   at Microsoft.Data.SqlClient.SNINativeMethodWrapper.SNIAddProvider(SNIHandle, ProviderEnum, AuthProviderInfo& )
   at Microsoft.Data.SqlClient.TdsParserStateObjectNative.EnableSsl(UInt32&, Boolean, String)
   at Microsoft.Data.SqlClient.TdsParser.EnableSsl(UInt32, SqlConnectionEncryptOption, Boolean, String)
   at Microsoft.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(SqlConnectionEncryptOption, Boolean, Boolean, Boolean& , Boolean& , Boolean, String)
   at Microsoft.Data.SqlClient.TdsParser.Connect(ServerInfo, SqlInternalConnectionTds, Boolean, Int64, SqlConnectionString, Boolean)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo, String, SecureString, Boolean, TimeoutTimer, Boolean )
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo, String, SecureString, Boolean, SqlConnectionString, SqlCredential, TimeoutTimer)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer, SqlConnectionString, SqlCredential, String, SecureString, Boolean)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity, SqlConnectionString, SqlCredential, Object, String, SecureString, Boolean, SqlConnectionString , SessionData , Boolean , String , DbConnectionPool )
   at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions, DbConnectionPoolKey, Object, DbConnectionPool, DbConnection, DbConnectionOptions)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool, DbConnection, DbConnectionOptions, DbConnectionPoolKey, DbConnectionOptions)
   at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection, DbConnectionOptions, DbConnectionInternal)
   at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection, DbConnectionOptions, DbConnectionInternal )
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection, UInt32, Boolean, Boolean, DbConnectionOptions, DbConnectionInternal& )
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection, TaskCompletionSource`1, DbConnectionOptions, DbConnectionInternal& )
   at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection, TaskCompletionSource`1, DbConnectionOptions, DbConnectionInternal, DbConnectionInternal& )
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection, DbConnectionFactory, TaskCompletionSource`1, DbConnectionOptions)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1, SqlConnectionOverrides )
   at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides)
   at Hangfire.SqlServer.SqlServerStorage.CreateAndOpenConnection()
   at Hangfire.SqlServer.SqlServerStorage.UseConnection[T](DbConnection, Func`2)
   at Hangfire.SqlServer.SqlServerStorage.UseConnection(DbConnection, Action`1 )
   at Hangfire.SqlServer.SqlServerStorage.Initialize()
   at Hangfire.SqlServerStorageExtensions.UseSqlServerStorage(IGlobalConfiguration , String )
   at Program.<>c__DisplayClass0_1.<<Main>$>b__4(IGlobalConfiguration) in D:\Users\jwood\source\repos\Railtrax\TrackTrace.WorkerServices\Program.cs:line 22
   at Hangfire.HangfireServiceCollectionExtensions.<>c__DisplayClass1_0.<AddHangfire>b__14(IServiceProvider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite, RuntimeResolverContext)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite, TArgument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey, Func`2)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type, ServiceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider, Type)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider)
   at Hangfire.HangfireServiceCollectionExtensions.<>c__DisplayClass14_0`1.<TryAddSingletonChecked>b__0(IServiceProvider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite, RuntimeResolverContext)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite, TArgument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey, Func`2)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type, ServiceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider )
   at Program.<<Main>$>g__ConfigureJobs|0_2(IHost) in D:\Users\jwood\source\repos\Railtrax\TrackTrace.WorkerServices\Program.cs:line 54
   at Program.<Main>$(String[]) in D:\Users\jwood\source\repos\Railtrax\TrackTrace.WorkerServices\Program.cs:line 48

Can anyone see what might be happening, or assist me in troubleshooting?

Here's my setup. The exception appears to be happening on the line that calls host.Run().

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((context, services) =>
    {
        services.AddHangfire(configuration => configuration
            .UseRecommendedSerializerSettings()
            .UseSimpleAssemblyNameTypeSerializer()
            .UseSqlServerStorage(context.Configuration.GetConnectionString("HangfireConnection")));
        services.AddHangfireServer(options => options.Queues = new[] { JobHelper.TrackTraceQueueName });

        services.AddDbContext<TrackTraceDbContext>(options =>
        {
            string? connectionString = context.Configuration.GetConnectionString(connectionName);
            if (connectionString == null)
                throw new Exception("Connection string not configured.");

            options.UseSqlServer(
                connectionString,
                builder => builder.MigrationsAssembly("TTRailtraxEntities"));
        });

        services.AddScoped<IEdiImporterWorkerService, EdiImporterWorkerService>();
        services.AddScoped<IEtaBuilderWorkerService, EtaBuilderWorkerService>();

        services.AddScoped<IHeartbeatWorkerService, HeartbeatWorkerService>();
    })
    .UseWindowsService(x => x.ServiceName = ServiceName)
    .Build();

host.Run();

I'm building a Windows Service, but the exception happens when I just run the app directly.

odinserj commented 1 year ago

Please try to upgrade the Microsoft.Data.SqlClient to its latest version, or, if you are using assembly trimming, try to disable it and see if the issue is gone.

SoftCircuits commented 1 year ago

@odinserj Yes! It was the Trim unused code option. I unchecked that and now it's working. Many thanks!