realm / realm-dotnet

Realm is a mobile database: a replacement for SQLite & ORMs
https://realm.io
Apache License 2.0
1.25k stars 163 forks source link

Unable to use the IRealmObject interface with .Net Framework 4.8 #3436

Open crleblanc opened 1 year ago

crleblanc commented 1 year ago

What happened?

I'm working on a project that is using .Net Framework 4.8 and have been having great success with Realm. It's an amazing project!

However, I am unable to use the IRealmObject interface when implementing a realm class, as the docs suggest. Instead I can use the older approach of subclassing RealmObject. It sounds like this is deprecated and will eventually be unsupported or removed. Interfaces are much more flexible so I would prefer to switch to them.

I created two VS projects, one using Framework 4.8 that shows the errors I mentioned and another using .Net 7 which works as expected. Here is the repo with the example code: https://github.com/crleblanc/realm-dotnet-interfaces.

The NuGet Realm package indicates Net Standard 2.0 is supported, and Framework 4.8 conforms to this.

The errors I'm getting at build time for this example are mentioned in the log output section of this report.

My guess would be there's an issue with the Fody generator but I'm new to C# so that's just a guess.

Thanks for any help.

Repro steps

  1. Clone the files in https://github.com/crleblanc/realm-dotnet-interfaces.
  2. Restore the nuget packages for the realm-dotnet-framework-4.8 project, restart VS if necessary.
  3. Build the realm-dotnet-framework-4.8 project which should raise the errors mentioned above.

Version

11.4.0

What Atlas Services are you using?

Local Database only

What type of application is this?

Console/Server

Client OS and version

Windows 11 Enterprise

Code snippets

See https://github.com/crleblanc/realm-dotnet-interfaces

Stacktrace of the exception/crash you're getting

No response

Relevant log output

Build started...
1>------ Build started: Project: realm-dotnet-framework-4.8, Configuration: Debug Any CPU ------
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.Accessor'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.IsManaged'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.IsValid'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.IsFrozen'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.Realm'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.ObjectSchema'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.DynamicApi'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'IRealmObjectBase.BacklinksCount'
1>H:\realm-dotnet-interfaces\realm-dotnet-framework-4.8\Program.cs(13,53,13,65): error CS0535: 'ImplementsRealmInterface' does not implement interface member 'ISettableManagedAccessor.SetManagedAccessor(IRealmAccessor, IRealmObjectHelper?, bool, bool)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build started at 5:04 PM and took 01.214 seconds ==========
papafe commented 1 year ago

Hi @crleblanc, thanks for your report, it looks like there's an issue with the source generator with .NET Framework. Thanks a lot for the reproducible example, that's extremely helpful. I'll take a look. For now feel free to use the classes deriving from RealmObject. It's true that we're going to deprecate it at some point, but it's not something we have planned yet, and switching to the new interface-based classes should be relatively easy 😄

crleblanc commented 1 year ago

Thanks @papafe , I agree that using RealmObject is the best approach. I'm glad to hear it'll be supported for a while. Thanks for looking into this issue.

papafe commented 11 months ago

@crleblanc I had some time to give this a look, and it seems that the issue here is not .NET Framework per-se, but the legacy project style (instead of the "SDK-style").

If you use your example .NET 7 project and set the target to .NET Framework 4.8 (and language version to 10.0, otherwise it will complain about global usings...) in the csproj you can see it works:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net48</TargetFramework>
    <LangVersion>10.0</LangVersion>
    <RootNamespace>realm_dotnet_7</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
</PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Realm" Version="11.4.0" />
  </ItemGroup>

</Project>

So far I didn't manage to find any reliable information regarding this, but I suspect that there could be a difference in the way the packages are treated that is causing issues with the source generator.

I can imagine this is no easy feat, but have you maybe tried to convert your project to the new SDK-style?