Prism + Log4Net build error : "Cannot resolve dependency to assembly log4net" - reflection

I am trying to add log4net support in a Prism application. Unfortunately i get the following error for each prism modules :
Error 101 Unknown build error, 'Cannot resolve dependency to assembly 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.' [PRISM MODULE 1 PROJECT NAME]
Error 101 Unknown build error, 'Cannot resolve dependency to assembly 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.' [PRISM MODULE 2 PROJECT NAME]
ect ...
I set up the logger as follow :
I added log4net assembly reference to both the main app, and the bootstrapper.
I added log4net configuration to the app.config file.
I added [assembly: log4net.Config.XmlConfigurator(Watch = true)] to the App.xaml.cs file.
I created a logger implemeting ILoggerFacade and overwrote CreateLogger() in the Bootstrapper to make it return my custom logger.
That's it.
If i try to build, it fails with the error mentioned above for each prism module project.
The only work around i found was to manually add log4net references to each prism modules projects which, i think, kind of defeats the abstraction between ILoggerFacade and the dependencies of the actual implementation.
The error suggest to use the ReflectionOnlyAssemblyResolve event, but i don't see how it could help here as it is a build error, not runtime.
Any suggestion ? :-)

Ok i found the problem, each modules were referencing the bootstrapper which is just wrong, i removed that dependency and VOILA, fixed !

Related

Why does a force downgrade causes an assembly load exception in .Net Core?

I have a sample solution with a console and library project. Both reference the same nuget but a different version. The console project also has a reference to the library project. So the structure is like this:
- Solution
- ConsoleApp
- Project Reference: Library
- Nuget: NServiceBus.RabbitMQ (5.2.0)
- Library
- Nuget: NServiceBus.RabbitMQ (6.0.0)
You can find the solution here.
Since Nuget uses the nearest wins rule, the nuget package that gets resolved is version 5.2.0. This is what I want, so far so good. But when I run the application and run a method of the Library I get the following exception:
Could not load file or assembly 'NServiceBus.Transport.RabbitMQ, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
In .NET Framework I would solve this with an assembly redirect. But that isn't available in .Net Core. I always thought that .Net Core solves this automatically by using the deps.json file. There I see the following statement:
"Library/1.0.0": {
"dependencies": {
"NServiceBus.RabbitMQ": "5.2.0"
},
"runtime": {
"Library.dll": {}
}
}
But still at runtime he tries to resolve the 6.0.0 version. I'm using the latest .Dot Net 3.1.X SDK.
I'm I doing something wrong or does this seem like a bug?
For the record, this is a simple sample project. The actual situation where I need this is much more complex. I also do understand that doing this can cause runtime exceptions while running the application.
It appears to be by design.
A little bit of searching, I found this: https://github.com/dotnet/fsharp/issues/3408#issuecomment-319466999
The coreclr will load an assembly of the version or higher than the reference. If the assembly discovered is lower than the reference then it fails.
Also this: https://github.com/dotnet/sdk/issues/384#issuecomment-260457776
downgrading the assembly version isn't supported on .NET Core
So, to confirm, I spent much more time than I intended looking/searching through https://github.com/dotnet/runtime. Eventually I found the assembly version compatibility method: https://github.com/dotnet/runtime/blob/172059af6623d04fa0468ec286ab2c240409abe3/src/coreclr/binder/assemblybindercommon.cpp#L49-L53
It checks all the components of the version separately, but if we look at just one, we can see what it's doing:
if (!pFoundVersion->HasMajor() || pRequestedVersion->GetMajor() > pFoundVersion->GetMajor())
{
// - A specific requested version component does not match an unspecified value for the same component in
// the found version, regardless of lesser-order version components
// - Or, the requested version is greater than the found version
return false;
}
As the comment says, the loader will reject the assembly if the assembly's version is lower than the requested version. In your case, assuming that the assembly version matches the package version (which it doesn't have to), your library is requesting version 6.0.0, but the assembly loader/binder, found version 5.2.0 on disk, which is lower. Hence, it rejects that dll, keeps looking, but then can't find a suitable version of the assembly on the probing path and eventually throws the FileLoadException.
What's not clear to me is if this assembly compatibility is checked only on the default assembly loader, or even if you add your own event handler to AssemblyLoadContext.Default.Resolving. You could try adding your own handler and when it requests the assembly of the higher version, you return the lower version assembly anyway. It might be a way to work around the issue.

Custom MsBuild Task fails with assembly loading errors

I have defined a custom MSBuild Task, using .netcore 5.0 and it is accessible here.
The "Application" project uses "SnykTaskFile" in its build process.
When I build "Application" I got the following error :
System.BadImageFormatException: Could not load file or assembly
'System.Diagnostics.Process, Version=5.0.0.0,
If I remove the following code from "SnykTaskFile" :
var processInfo = new ProcessStartInfo();
processInfo.FileName = "cmd";
processInfo.WorkingDirectory = Location;
Process.Start(processInfo);
And build the "Application" again, it builds successfully, however if I have a logic around "Location" :
if (Location.Contains("...."))
{
return false;
}
It throws another error :
System.IO.FileNotFoundException: Could not load file or assembly
'System.Runtime, Version=5.0.0.0,
According to the answer here and the discussion "Custom Tasks don't work with NET5.0" in git hub, it seems I should use netstandard 2.0 for task project type.

InvalidOperationException: Could not find 'UserSecretsIdAttribute' on assembly

After deploying ASP.NET Core app to azure and opening the site, I get the following error:
InvalidOperationException: Could not find 'UserSecretsIdAttribute' on
assembly '******, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.
The exception details also include that the error happens at Startup.cs on this line of code:
builder.AddUserSecrets();
Thank you
There was an update to the user secrets module just recently. Version 1.0.1 and up now requires you specify an assembly-level attribute for the id of the user secrets, or as a fallback, the way it was previously in project.json.
Here is the announcement on GitHub: https://github.com/aspnet/Announcements/issues/209
You can define the secrets id in the .csproj like this:
<PropertyGroup>
<UserSecretsId>aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed</UserSecretsId>
</PropertyGroup>
This generates the following assembly-level attribute. Alternatively, instead of adding it in the .csproj file, you can of course add it yourself e.g. to Startup.cs:
[assembly: UserSecretsId("aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed")]
Also, you should use:
builder.AddUserSecrets<Startup>();
It will search for that attribute in the assembly of the given type, in this case I used the Startup class.
Note: this will be deprecated in 2.0: (1.0.2 and 1.1.1 have marked it obsolete)
builder.AddUserSecrets();
I checked the source code for the user secrets configuration, and calling AddUserSecrets() without the type does this:
var attribute = entryAssembly.GetCustomAttribute<UserSecretsIdAttribute>();
if (attribute != null)
{
return AddUserSecrets(configuration, attribute.UserSecretsId);
}
// try fallback to project.json for legacy support
try
{
var fileProvider = configuration.GetFileProvider();
return AddSecretsFile(configuration, PathHelper.GetSecretsPath(fileProvider));
}
catch
{ }
// Show the error about missing UserSecretIdAttribute instead an error about missing
// project.json as PJ is going away.
throw MissingAttributeException(entryAssembly);
It's trying to find the UserSecretsId attribute on your assembly, and failing that, checking if it could find it in project.json. Then (as commented) returns an error about the missing attribute as they wouldn't want to complain about project.json anymore as it is being deprecated.
I want to add to this answer, for those in my situation.
I am writing a .NET Core console app, trying to use the secrets manager (not sure it's meant for console apps). The only way I was able to rid myself of the error was using the assembly level attribute on the assembly where I was using the secrets manager.
As I said, I am not sure if the secrets manager is meant for console apps. So maybe there is an issue with .xproj files vs. .csproj files.
My .NET Core 3.1 Worker Service required additional setup (more than a Web project).
In Program.cs in the CreateHostBuilder method I needed this:
.ConfigureAppConfiguration((ctx, builder) =>
{
// enable secrets in development
if (ctx.HostingEnvironment.IsDevelopment())
{
builder.AddUserSecrets<Worker>();
}
})
But (unlike my Web project) I explicitly needed to add this nuget package:
install-package Microsoft.Extensions.Configuration.UserSecrets
After that I could access secrets.

'bootstrap' is not a valid script name. The name must end in '.js'

I'm learning asp.net and so I'm trying to build up the project named "Wingtip Toys" from MSDN.
The project is developed on VS 2013 and I have VS 2012. When I try to add Bootstrap per the instruction from here I get the error on runtime in browser.
Server Error in '/' Application.
'bootstrap' is not a valid script name. The name must end in '.js'.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: 'bootstrap' is
not a valid script name. The name must end in '.js'.
when I add the .js on the master page it shows me to another error:
The assembly 'System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not contain a Web resource that has the name 'bootstrap.js'. Make sure that the resource name is spelled correctly.
I also add the CSS file to Bundle.config but still the same result. I already have the NuGet package available, like for the jQuery.js error, but I'm unable to sort this out yet.
Here's what worked for me.
I added this to my BundleConfig.cs file:
ScriptManager.ScriptResourceMapping.AddDefinition("bootstrap", new ScriptResourceDefinition
{
Path = "~/scripts/bootstrap.min.js",
DebugPath = "~/scripts/bootstrap.js",
LoadSuccessExpression = "bootstrap"
});
Please go to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solutions.
In Browse, search for: AspNet.ScriptManager.bootstrap
If your version of bootstrap is higher than AspNet.ScriptManager.bootstrap first uninstall bootstrap and then install AspNet.ScriptManager.bootstrap
go to:
Tools
NuGet Package Manager
Manage NuGet Packages for Solutions...
search for Bootstrap.css
install it
try to run your app

Could not load file or assembly or one of its dependencies

I changed some names of namespaces, assemblies in one of existing project (C# and ASP.NET). But when I try to debug it; I get this error.
Could not load file or assembly 'HR' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).
I have replaced DFI with HR in the code.
Sometime I have got such error and began to research how to resolve it. After all I just have added such attribute to web.config compilation node:
<compilation debug="true" tempDirectory="c:\temp" >
I hope that this can help and other people.
I also got this terrible error and found a solution for this...
Right Click on the Solution name
Click Clean Solution
Restart
Goto project Properties >> Build
Change Configuration to Release
Start Debugging (F5)
1) , 2)
4) , 5)
Hope this will help you also.
If your project compiles, you may be referencing the assembly in a config file. I would check anywhere that you may be using late binding to reference a type. Also check your #Page directives as you may have an assembly qualified type reference that is referring to the old HR assembly.

Resources