ReactiveUI - The type 'IScheduler' is defined in an assembly that is not referenced - reactiveui

I'm trying to subclass ReactiveList so it responds to changes in a ReactiveDictionary I have written, rather than a parent List.
This is the class and constructor signature for the ReactiveList subclass.
public class ReactiveDictionaryDerivedList<TKey, TValue, TDerived> : ReactiveList<TDerived>, IReactiveDerivedList<TDerived>
{
public ReactiveDictionaryDerivedList(
IReadOnlyReactiveDictionary<TKey, TValue> dict,
Func<TValue, TDerived> selector,
Func<TValue, TDerived, bool> derivedValueFinder,
IScheduler scheduler)
{
}
Here are the dependencies I have in the project. Notice that I'm using the 4.0.0 preview release of System.Reactive, since this is installed by the ReactiveUI 8.0.0 alpha. (I'm using the ReactiveUI alpha as this seems to be what is recommended these days)
<packages>
<package id="ReactiveUI" version="8.0.0-alpha0113" targetFramework="net452" />
<package id="ReactiveUI.WPF" version="8.0.0-alpha0113" targetFramework="net452" />
<package id="Splat" version="2.0.0" targetFramework="net452" />
<package id="System.Reactive" version="4.0.0-preview00001" targetFramework="net452" />
</packages>
The problem is that the class doesn't compile because of the error:
error CS0012: The type 'IScheduler' is defined in an assembly that is not referenced.
You must add a reference to assembly 'System.Reactive.Interfaces, Version=3.0.1000.0,
Culture=neutral, PublicKeyToken=94bc3704cddfc263'.
Any ideas how to resolve would be appreciated. Advice on the recommended versions for ReactiveUI and System.Reactive would also be nice.

In my WPF app I had to install the System.Reactive.XXXXX packages with version 4.0.0-preview00001 (Core, Interfaces, Linq, PlatformServices, Windows.Threading, Windows.Forms).
All these packages come with the System.Reactive.Compatibility package (nuget link):
Reactive Extensions (Rx) Compatibility Library for enabling v3 apps to
work with v4
You should try using it in your project.

Unfortunately something fishy is going on with dependencies at the moment. But for the current 8.0 version it's recommended to install System.Reactive 3.1. That's the only version 8.0 is tested against.
If you start using PackageReference for your projects, you won't need to define the System.Reactive dependency yourself, but it's picked up by the package manager. But that might not work (yet?) with WPF.
See: https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files

Related

Use a .nuspec file/script to automatically install nuget packages into a new project

I am trying to automate the process of installing nuget packages into new visual studio projects. My idea is to reduce the time it takes to source all the packages via the nuget package manager, by specifying the packages in a custom file that can be run to install these packages. Therefore only requiring every new project to include this file and running it each time. I'm very new to nuget and have been assigned this task without much prior knowledge. I was advised that .nuspec route would lead me in the right direction, since it contains the meta data about a package. Although since consumers don't have direct access to the .nuspec file of a package, I am failing to understand how it can be used as part of this automation. I have also heard about automatic package restore, but since that only works for lost reference, I don't see how it will help in new projects that haven't necessarily referenced anything to do with that project.
note that you cannot simply drop a pre-built packages.config file into a new project and expect it to work. When installing, NuGet modifies the project file (.csproj) to include references and uses packages.config for downloading missing files (and update/conflict logic).
Using VS 2017 (released stable versions 15.2 and higher) and the PackageReference style of referencing projects, you can simply drop a Directory.Build.props file into the root of your solution containing all the projects you need:
<Project>
<ItemGroup>
<PackageReference Include="Autofac" Version="3.5.2 />
<PackageReference Include="Topshelf" Version="3.2.0 />
</ItemGroup>
</Project>
This will add these NuGet packages to all new projects in the solution without the need for the .csproj files to be modified. (note that after adding/editing this file, you need to close and re-open the solution. this should be fixed in the upcoming VS 2017 15.3 update for editing the file).
Nuget already supports automation of installation and we can use nuget commandline to achieve this
Everytime you add a nuget package in Visual Studio,it gets add to a file called packages.config file.
E.g. will look like this
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net451" />
<package id="Microsoft.Owin" version="3.1.0" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net451" />
<package id="Microsoft.Owin.Hosting" version="3.1.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net451" />
<package id="Owin" version="1.0" targetFramework="net451" />
<package id="Topshelf" version="3.2.0" targetFramework="net451" />
</packages>
Every project you have in your solution will have packages.config file. You can go to the parent folder of all the projects and simply run comand 'nuget restore', it will get all the packages for you.
For this to work, nuget.exe needs to be downloaded separately .More details on the nuget command line can be found here and here's the commandline reference
Edit:
Thanks #Martin Ullrich pointing out.Just to be clear, The above method will not add the references to project file automatically,it will only get the packages to the packages folder.In VS2017,the support is there which #Martin's answer addresses.
Hope this helps!

Creating a NuGet package that includes other Nuget Packages - NewtonSoft Reference Errors

Getting started with creating NuGet packages for various common libraries, that were up to now typically added as a project to a solution.
Using TFS 2017 to build and deploy the NuGet packages to the Package Manager built into TFS 2017.
I have an issue with dependencies and don't fully understand how to resolve it. It's also a little complicated to detail; so here goes.
I have built a class library that has a NuGet package installed - The package is SharpRaven 2.2.0
SharpRaven has a dependency on NewtonSoft.Json >= 6.0.8
This results in Newtonsoft.Json being added to my class library. By default NewtonSoft.Json 6.0.8 is installed.
I then package up my class library as a NuGet package - Called it TestNuGet
TFS is building the nuget by using the .csproj file and not the nuspec
When I use this new package in projects I see there are dependencies for SharpRaven and Newtonsoft (if neither of those are currently installed in the project).
My problem starts with Newtonsoft.Json.
Take the following projects:
Solution A and B
- Already has Newtonsoft 9.0.1.
- Install TestNuGet, so SharpRaven is also added
- Project is fine, no errors when using TestNuGet
Solution C
- Already has Newtonsoft 9.0.1.
- Install TestNuGet, so SharpRaven is also added
- Errors when calling TestNuGet; error below:
Solution C
- Remove Newtonsoft 9.0.1
- Install TestNuGet, SharpRaven and Newtonsoft 6.0.8 installed
- Project is fine. No errors
- Update Newtonsoft
- Get Errors again as before
If i update NewtonSoft to 9.0.1 in TestNuget and rebuild it I get exactly the same issues above.
There are no projects within Solution C that are referencing anything other than 9.0.1.
It seems to me that when adding a NuGet package NuGet looks at all of the packages within and uses those dependencies, ignoring what is already added to the TestNuget.
So the question, i think - Is there a way to instruct nuget to use the newtonsoft version i added to TestNuget and to not try and meet the dependency sharpraven is calling for? Something to add to the Packages.config perhaps?
Would I be better using a nuspec file? is there more that can be set in this to control how the package is built?
Or is there something I'm missing in my usage of these packages.
Error being thrown when trying to use the package is:
Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Binding Redirect from the web.config of the solution that will not run looks as this:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
I also tried adjusting the redirect to encapsulate 9.0.1
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.1.0" newVersion="9.0.1.0" />
</dependentAssembly>
The issue here is that an assembly has a reference to a version 6 of NewtonSoft.Json which is not found at runtime since only a higher version is present.
This is usually worked around with binding redirects. NuGet should automatically generate the necessary binding redirects into runnable (exe, web apps) projects using packages.config when installing packages.
For PackageReference based projects it is sometimes (test projects, plugin-library, …) required to also tell msbuild to automatically generate the needed binding redirects based on the resolved assemblies. This can be done by adding this to the csproj file:
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
However this does not protect against actual breaking changes that could have occurred in new major versions of a library.
Also note that these binding redirects may be overwritten by the binding redirects of other applications re-using the built assembly (parent projects, plugin-system etc).

Reference system nuget from .net standard library

I tried adding some standard nugets to my .Net standard 2.0 library project. But when compiling I get the following type of errors:
The type 'IDisposable' exists in both 'System.Runtime, Version=4.1.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and
'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
and
Predefined type 'System.Object' is not defined or imported
Here is my project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Net.WebSockets" Version="4.3.0" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.7.0" />
</ItemGroup>
</Project>
Both nugets declare support for .Net Standard. I used VS 15.3 preview 2.
Is there some magic setting for .Net Standard 2.0 libraries I need to be aware of? What do I need to do to get a .Net standard 2.0 library compiling?
This happens due to a bug in the conflict resolution targets / infrastructure that is fixed in current 2.0.0-preview2 builds. These aren't included in VS 2017 15.3 preview 2.0 and need to be installed separately (e.g. from the links in https://github.com/dotnet/cli/tree/release/2.0.0).
Note that VS 2017 15.3 now uses an "SDK resolver" that looks for a global.json in the opened project and uses the SDK version it resolves to (or latest) instead of the bundled SDKs.

How to add nuget packages and run custom project wizard?

I built my own project template. When a project is created with the template, a custom wizard is launched that allows the user to edit the project that was created.
The problem is that I also need to add some very simple nuget packages to the created project (just mvvmlight, MyToolkit and 1 other). To do this I added a WizardData element to my vstemplate with the right packages.
Here comes the problem: in order to launch my custom wizard, I need to put a reference to my wizard inside the WizardExtension element. But in order to install the nuget packages automatically I need to place a reference towards NuGet.VisualStudio.TemplateWizard inside my WizardExtension element, and the WizardExtension can only have one class that it will instantiate, but I have 2 that need to run.
So how do I solve this?
Here's the code that launches my own wizard. Now I just need the NuGet packages to install too:
<WizardExtension>
<Assembly>PartyTemplateWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=7eb2f41084fd4cd5</Assembly>
<FullClassName>PartyTemplateWizard.Wizard</FullClassName>
</WizardExtension>
<WizardData>
<packages repository="template">
<package id="MvvmLight" version="4.1.27.0" />
<package id="MvvmLightLibs" version="4.1.27.0" />
<package id="MyToolkit" version="1.14.0" />
<package id="linqtotwitter" version="2.1.06" />
</packages>
</WizardData>
Does anyone have a solution?
Well, I came across the same issue and was disappointed to find no answer for this post. Now I've got the answer and I'm posting it.
There cannot be two wizard extensions. So you need to instantiate NuGet from your custom wizard (see below) and delegate all methods to this instance.
Add these lines to the RunStarted method:
Assembly asm = Assembly.Load("NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a");
wizard = (IWizard)asm.CreateInstance("NuGet.VisualStudio.TemplateWizard");
And, call the method on the instance like this:
wizard.RunStarted(automationObject, replacementsDictionary, runKind, customParams);
Similar way delegate to the wizard instance in all methods.
Instead of trying to place multiple references in one WizardExtension element - you can add multiple WizardExtension elements (one for each assembly reference).
For example:
<WizardExtension>
<Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
<WizardExtension>
<Assembly>PartyTemplateWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=7eb2f41084fd4cd5</Assembly>
<FullClassName>PartyTemplateWizard.Wizard</FullClassName>
</WizardExtension>
<WizardData>
<packages repository="extension" repositoryId="your-extension-id-here">
<package id="MvvmLight" version="4.1.27.0" />
<package id="MvvmLightLibs" version="4.1.27.0" />
<package id="MyToolkit" version="1.14.0" />
<package id="linqtotwitter" version="2.1.06" />
</packages>
</WizardData>
References used:
Xamarin Forms Templates (you can refer this vstemplate file in the repository)
Packages in Visual Studio templates
How to specify two wizard assemblies under tag in project template to create mvc4 application (vs2010)
Disclaimer: I have tested this on Visual-Studio-2015 only; not on Visual-Studio-2012 (although a quick look through the answers on this link seems to indicate that it is supported on VS2012 too)

Should NuGet.VisualStudio.Interop.dll be in the GAC to use it as a wizard?

I am creating a project template. I would like to have it auto install unity and prism via NuGet.
I read here how to do that. I setup my vstemplate file like that page indicates:
<WizardExtension>
<Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
<WizardData>
<packages>
<package id="CommonServiceLocator" version="1.0" />
<package id="Prism" version="4.1.0.0" />
<package id="Prism.UnityExtensions" version="4.1.0.0" />
<package id="Unity" version="2.1.505.0" />
</packages>
</WizardData>
It seems to be setup right, but it does not work. When I try to use my template I get this error message:
Could not add all required packages to the project. The following packages failed to install from 'C:\Users\MyUser\AppData\Roaming\Microsoft\VisualStudio\10.0\ProjectTemplatesCache\MyTemplate.zip'
I did some looking, and for a Wizard to work, it needs to be installed in the GAC. I ran this command:
gacutil.exe /l NuGet.VisualStudio.Interop
And it returned:
The Global Assembly Cache contains the following assemblies:
Number of items = 0
So it seems it is not in the GAC. The question is: How does this work for everyone else then? If it needs to be in the GAC, then why is it not there automatically?
If not, then why does it not work (I am fairly sure it needs to be in the GAC though).
Note: I did find that dll here:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft Corporation\NuGet Package Manager\1.6.21215.9133
I found that I had missed this important part of the docs:
The template needs to specify where to find the package nupkg files. Currently two package repositories are supported:
Packages embedded inside of a VSIX package.
Packages embedded inside of the project/item template itself.
So, there is no way to get packages from the actual NuGet Repository.
Answer for this Question:
Open Visual Studio > Tools > Extensions and Updates > choose Online link and then right side search bar type NuGet Package Manager. Then Download and Install. Solves your problem

Resources