Skip to content
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

System.TypeLoadException : Could not load type 'System.Windows.IWeakEventListener' from assembly 'WindowsBase' #1466

Closed
WindingWinter opened this issue Aug 30, 2024 · 14 comments · Fixed by #1483
Assignees
Labels
Milestone

Comments

@WindingWinter
Copy link

WindingWinter commented Aug 30, 2024

This problem happens in nunit console 3.18.1 but not when I run in Resharper test runner.

Here's my main code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace Net80WindowsLib
{

    public class Person : INotifyPropertyChanged
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class MyWeakEventListener : IWeakEventListener
    {
        public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
        {
            if (managerType == typeof(PropertyChangedEventManager))
            {
                OnPropertyChanged(sender, (PropertyChangedEventArgs)e);
                return true;
            }
            return false;
        }

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Name")
            {
                var person = sender as Person;
                Console.WriteLine("Person's name changed to: " + person?.Name);
            }
        }
    }

}

And here's my csproject

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
	<UseWPF>True</UseWPF>
  </PropertyGroup>

</Project>

here's my test code:

using System.ComponentModel;
using Net80WindowsLib;
using NUnit.Framework;
using NUnit.Framework.Legacy;

namespace Net80WindowsTest
{
    [TestFixture]
    public class Net80TestClass
    {
        [Test]
        public void RunTest()
        {
            var person = new Person();
            var listener = new MyWeakEventListener();

            // Use PropertyChangedEventManager to add a weak event listener
            PropertyChangedEventManager.AddListener(person, listener, "Name");

            person.Name = "Alice";  // Triggers the listener
            person.Name = "Bob";    // Triggers the listener again
            ClassicAssert.AreEqual("Bob", person.Name);
        }
    }
}

And the test csproject

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
	<UseWPF>True</UseWPF>
	<OutputType>Library</OutputType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="NUnit" Version="4.2.1" />
	<PackageReference Include="Microsoft.Net.Test.Sdk" Version="17.10.0" />
	<PackageReference Include="NUnit.ConsoleRunner" Version="3.18.1" />
	<PackageReference Include="NUnit.Extension.VSProjectLoader" Version="3.9.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Net80WindowsLib\Net80WindowsLib.csproj" />
  </ItemGroup>

</Project>

And if I run the test in Resharper test runner, the test passes!

But if I run it in nunit console

set NunitConsole=C:\Users\USER\.nuget\packages\nunit.consolerunner\3.18.1\tools
call  "%NunitConsole%\nunit3-console.exe" "%slnFile%" --skipnontestassemblies --result="%testresultxml%"  --timeout=900000 > "%testresulttxt%"

And I will get the following error:

1) Error : Net80WindowsTest.Net80TestClass.RunTest
System.TypeLoadException : Could not load type 'System.Windows.IWeakEventListener' from assembly 'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
   at Net80WindowsTest.Net80TestClass.RunTest()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Seems like a bug but I don't rule out that it could be some config issue also. What could be the error?

@WindingWinter
Copy link
Author

It does seem like here's the same problem, #1383

@CharliePoole
Copy link
Collaborator

Can you clarify whether you are running the standard console runner or the netcore console runner? Check the "Runtime:" value when you run a program. It will either indicate .NET 6, .NET 8 or .NET Framework.

The standard runner (.NET Framework) and the two .NET Core builds have quite different feature sets and should probably not have the same package or executable names. They also can have quite different bugs. :-(

@WindingWinter
Copy link
Author

WindingWinter commented Aug 31, 2024 via email

@CharliePoole
Copy link
Collaborator

@WindingWinter Sorry...

When you run nunit3-console.exe SOME_FILE_NAME console output is produced. About 5 or 6 lines from the top there is a line stating "Runtime: XXXX". What is XXXX in your case?

@CharliePoole
Copy link
Collaborator

FYI see #1467

@OsirisTerje
Copy link
Member

OsirisTerje commented Aug 31, 2024

@WindingWinter I wrote about the different console programs here #1467 (comment)

If you use nunit3-console, you should see this:
image
I believe you always will see version v4.0 using this version of the tool.

If you use the dotnet tool nunit, you will see something like this:
image
Thus this is running under .net 6 (not sure why though, since this is a .net 8 app, and I do have .net sdk and runtime up)
image

Anyway, this way you can state what runner you're using.

If you have installed the dotnet tool in some other manner, I suggest you uninstall that, and install it as a dotnet tool. It makes life easier. :-)

PS1: One way people install the console is as a nuget package under the current test project. I never do that since that might interfere with the adapter if you're not careful.

PS2: Interesting though, the OS version are reported differently with these two variants of the console. Not sure why.

PS3: When using Resharper or Rider, they use an embedded version of the NUnit.Engine. It was version 3.12 some time ago, but I think they have upgraded lately. It is not version 3.18.1 though.

@CharliePoole
Copy link
Collaborator

On my local machine, I get net6.0 / net8.0 depending on which of the netcore versons I run.

FYI, prior to 3.18.1, their were two different .NET Core runners being packaged, making things even more confusing. In 3.18.1 I limited it to the .NET 6.0 build - see issue #1449. That has the advantage of running under 6.0, 7.0 or 8.0.

Also, the "Runtime:" line in the output shows the runtime under which the console is running, not the runtime for which it was built. So this can vary from machine to machine but will always allow you to distinguish between a .NET Framework version and a .NET Core version.

@CharliePoole
Copy link
Collaborator

So @WindingWinter Which is it for you? :-)

@WindingWinter
Copy link
Author

@CharliePoole , here's my runtime info from the nunit console output file:

NUnit Console 3.18.1+5e16ca2ef85f57f9f09bb41ff08feb8f3168a384 (Release)
Copyright (c) 2022 Charlie Poole, Rob Prouse
Sunday, September 1, 2024 6:59:50 AM

Runtime Environment
   OS Version: Microsoft Windows NT 6.2.9200.0
   Runtime: .NET Framework CLR v4.0.30319.42000

And here's my dotnet --info output:

E:\>dotnet --info
.NET SDK:
 Version:           8.0.400
 Commit:            36fe6dda56
 Workload version:  8.0.400-manifests.56cd0383
 MSBuild version:   17.11.3+0c8610977

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.400\

.NET workloads installed:
Configured to use loose manifests when installing new manifests.
There are no installed workloads to display.

Host:
  Version:      8.0.8
  Architecture: x64
  Commit:       08338fcaa5

.NET SDKs installed:
  8.0.400 [C:\Program Files\dotnet\sdk]

@CharliePoole
Copy link
Collaborator

@WindingWinter Ok, so after all those questions, it's just the standard console runner. :-)

That means it's possibly a bug in the .NET 8.0 agent or in TestCentric.Agent.Core, which has the agent common code. I'll try to create a repro locally to confirm it.

@WindingWinter
Copy link
Author

WindingWinter commented Sep 2, 2024

Seems related to this issue #1203. So my workaround is that I change the %nuget%\packages\nunit.consolerunner\3.18.1\tools\agents\net8.0\nunit-agent.runtimeconfig.json ( for net8.0-windows which I'm running under) to the below:

{
  "runtimeOptions": {
    "tfm": "net8.0-windows",
    "framework": {
      "name": "Microsoft.WindowsDesktop.App",
      "version": "8.0.0"
    },
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
      "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true
    }
  }
}

And now it works!

@CharliePoole
Copy link
Collaborator

Thanks. This will help with finding a solution to the issue.

@CharliePoole CharliePoole self-assigned this Sep 15, 2024
@CharliePoole CharliePoole added this to the 3.18.2 milestone Sep 15, 2024
@CharliePoole
Copy link
Collaborator

Fixed this by reordering how we look for dependencies when the test assembly uses Windows Forms , WPF or Asp .NET Core. In the case of this issue, it allows us to find the proper WindowsBase.

@CharliePoole
Copy link
Collaborator

This issue has been resolved in version 3.18.2

The release is available on:
GitHub.
NuGet packages are also available NuGet.org and
Chocolatey Packages may be found at Chocolatey.org

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants