dotnet/reactive

Version 3.1.1 has different DLL versions, depending on the platform.

LifeCoder45 opened this issue · 8 comments

When updating to the new Rx, and possibly the version just behind it, the version number of the various System.Reactive.* (Core, etc) seems to be different depending on what project target the Nuget is installed into.

The result of this is that all Observable related code breaks at runtime at least in our unit tests, and I assume in the Android, etc client as well.

When installed into a PCL, System.Reactive.Core comes from:

packages\System.Reactive.Core.3.1.1\lib\netstandard1.0\System.Reactive.Core.dll

When installed into a unit test project, System.Reactive.Core comes from:

packages\System.Reactive.Core.3.1.1\lib\net45\System.Reactive.Core.dll

Using the Visual Studio Properties window on Project > References > System.Reactive.*, the PCL has the following values:

Runtime Version: v4.0.30319, Version: 3.0.0.0

However, the unit test project has:

Runtime Version: v4.0.30319, Version: 3.0.1000.0

Running the single test in the following project produces the following output:

Test method RxTest.Unit.UnitTest1.TestMethod1 threw exception: 
System.IO.FileLoadException: Could not load file or assembly 'System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

    at RxTest.Lib.Class1.get_TestObservable()
   at RxTest.Unit.UnitTest1.TestMethod1() in C:\Users\joshu\Documents\Visual Studio 2015\Projects\RxTest\RxTest.Unit\UnitTest1.cs:line 14

I assume this is due to the Nuget DLL versions being out of sync, but am not familiar enough with this codebase to confirm.

Here is a little project, run the single unit test to see the issue:

https://github.com/LifeCoder45/rx-issue

It has a class in the PCL:

https://github.com/LifeCoder45/rx-issue/blob/master/RxTest.Lib/Class1.cs

public class Class1
{
    public IObservable<string> TestObservable => new Subject<string>();
}

That this single unit test accesses:

https://github.com/LifeCoder45/rx-issue/blob/master/RxTest.Unit/UnitTest1.cs

[TestMethod]
public void TestMethod1()
{
    var x = new Class1().TestObservable;
}

Hi @LifeCoder45 This is a result of #205. You need binding redirects in your app (and unit test project in this case). VS normally auto generates them. You might need an MSBuild property for some projects if it's not doing it by default:

https://msdn.microsoft.com/en-us/library/2fc472t2(v=vs.110).aspx

I had the same kind of issue with System.Reactive.Interfaces. Visual Studio 2015 added a binding redirect for System.Reactive.Core (3.0.3000.0) but not for Interfaces. Here is the XML snippet I added to app.config in order to get things running:

<dependentAssembly>
  <assemblyIdentity name="System.Reactive.Interfaces" publicKeyToken="94bc3704cddfc263" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-3.0.1000.0" newVersion="3.0.1000.0" />
</dependentAssembly>

I blogged about it for my future reference.

Why are System.Reactive.Core and System.Reactive.Interfaces not sharing the same version number? This caused some confusion while investigating the root of the problem.

@epsitec this is likely due to the fact that we only need to build System.Reactive.Interfaces for net45 and netstandard1.0 - which platform were you installing into at the time?

@shiftkey these are the platforms:

  • portable assembly defined as netstandard1.3. It refers to core 3.0.3000.0 and interfaces 3.0.0.0.
  • test assembly defined as net46. It refers to core 3.0.3000.0 and interfaces 3.0.1000.0.

This has been fixed in the v4.0 alpha's on the MyGet feed

Have you considered fixing the issue in 3.X and releasing a new version? Projects (e.g Powershell) have no easy way to add assembly redirects.

There are no assembly redirects to add -- just make sure that the facades are in the same directory as the new dll. Would love to have you try it out and confirm. Install both the System.Reactive and System.Reactive.Compatibility packages to have all the libraries you need for v3 compat and v4.

We cannot release a 3.x version with "the same" version number across assemblies because of issues that lead to #205 being designed and implemented. The surface area across the libraries was not the same and that lead to problems. The only fully-correct way to fix it with the old assembly scheme was to do what we did in #205. We realize that was painful and that's why we consolidated the types into a single library as a way to remedy all of the underlying issues.

@onovotny apologies, I should have explained my scenario.

We have a set of .NET 4.5.2 DLLs that depend on Rx, which we publish via our internal Nuget feed. We have a few .NET 4.6 projects that depend on those packages (and on Rx).

The problem is that the 4.6 projects are referencing the 4.6 Rx DLLs, whilst the .NET4.5.2 DLLs reference the 4.5.2 Rx DLLs. As you may have guessed by now, this is why I was talking about assembly redirects. I had not taken into account the work done on #205. We've retargeted the 4.6 projects to 4.5.2 for now and will revise the versions in the nearby future (perhaps when Rx v4 comes out).