Search code examples
wpf.net-core.net-core-3.0fodyfody-propertychanged

Can Fody and its plugins be used with .NET Core (3.0)?


As the title says, I'm having trouble getting Fody, and the plugin Fody.PropertyChanged, to work in .NET Core 3.0, or any .NET Core version. Reading the issues on the respective GitHub pages doesn't answer my question, nor am I able to find any relevant answers.

Once installed I cannot run my WPF project anymore and I am given the following error:

The target process exited without raising a CoreCLR started event.
Ensure that the target process is configured to use .NET Core.
This may be expected if the target process did not run on .NET Core.
The program '[21820] CalculationToolsApp.exe' has exited with code -2147450749 (0x80008083).

Any suggestions?

EDIT: I found out that I (maybe) cant use "Fody.Costura" with "Fody.PropertyChanged" like this in the FodyWeavers.xml file:

<Weavers>
  <PropertyChanged />
  <Costura />
</Weavers>

Which shouldn't be a problem because with .NET Core I can create a single file application anyway. Removing the Costura reference from the FodyWeavers.xml solved my problem!


Solution

  • It should work. Fody is compatible with .NET Standard.

    • Create a new WPF app using the WPF App (.NET Core) template in Visual Studio 2019 or using the dotnet new wpf command
    • Install the Fody and PropertyChanged.Fody NuGet packages
    • Add a file named "FodyWeavers.xml" with the following contents to the project:

      <Weavers>
          <PropertyChanged />
      </Weavers>
      
    • Build

    If you then decompile the assembly using a decompiler such as for example dotPeek, you should see the injected code as expected, e.g.:

    public string GivenNames
    {
        // Method get_GivenNames with token 06000009
        get
        {
            return this.<GivenNames>k__BackingField;
        }
        // Method set_GivenNames with token 0600000A
        set
        {
            if (string.Equals(this.<GivenNames>k__BackingField, value, StringComparison.Ordinal))
                return;
            this.<GivenNames>k__BackingField = value;
            this.<>OnPropertyChanged(<>PropertyChangedEventArgs.FullName);
            this.<>OnPropertyChanged(<>PropertyChangedEventArgs.GivenNames);
        }
    }