2

It appears that for some reason, Roslyn on .NET Core is throwing an error when a class that inherits from Dictionary is accessed.

CS0012: The type 'Dictionary<,>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Collections, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

My syntax tree looks like so:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using JQL.Core;

namespace RoslynCompileSample
{
    public class Writer
    {
        public object LinqIt(string outKey, Dictionary<string

            IEnumerable<TestClass>> db)
        {
            return db[outKey] = ({$linq
            });
        }
    }
}

And my references:

MetadataReference[] references = new MetadataReference[]
{
    MetadataReference.CreateFromFile(typeof(JQLQuery).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(DynamicAttribute).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(System.Collections.Generic.Dictionary<,>).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(System.Collections.Generic.Dictionary<string,object>).Assembly.Location)
};

My class

    public class TestClass : Dictionary<string, object>
    {
        public int age { get; set; }

        public TestClass()
        {
            this.age = 10;
        }
    }

Dictionary works if the object is defined from within the Roslyn SyntaxTree. If any Dictionary or inherited objects are passed in, I get the error.

Any idea what may be causing this? My collections version is actually 4.3.0 so not sure why it's even asking for a lower version.

user2292759
  • 159
  • 1
  • 9
  • Looks like your packages folder, or an assembly your using is referencing or finding the wrong assembly. Sometimes clearing your packages folder helps, good luck – johnny 5 Jun 16 '18 at 23:10
  • `Dictionary{K,T}` lives in the `System.Private.CoreLib.dll`, so `typeof(System.Collections.Generic.Dictionary<,>).Assembly.Location` returns path to it and, of course, it isn't `System.Collections.dll`. So you need to manually add reference on the `System.Collections.dll`. But I'm a little confused that Roslyn wants reference at System.Collections... Can you post a corresponding diagnostic message from Roslyn? – George Alexandria Jun 16 '18 at 23:44
  • This is the diagnostic I receive from Roslyn. "CS0012: The type 'Dictionary<,>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Collections, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.\nCS0021: Cannot apply indexing with [] to an expression of type 'TestClass'\n I get the indexing[] error because it does not see my class as inheriting Dictionary which is the real problem. :\ Unfortunately my error persists :\ – user2292759 Jun 16 '18 at 23:48
  • "it does not see my class as inheriting Dictionary" actually you didn't show in the question a class that must be inherited from Dictionary. Please, provide a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) – George Alexandria Jun 16 '18 at 23:56
  • @GeorgeAlexandria It's a very basic class. Just inherits dictionary and has one variable. Not much going on here. Any ideas? – user2292759 Jun 17 '18 at 00:00
  • Well, as I pointed out, just add reference to the `System.Collections.dll`. – George Alexandria Jun 17 '18 at 08:46
  • @GeorgeAlexandria Thanks for the help. I thought that is what I was doing by by pointing directly to Dictionary<,> in references but had to load the specific version it asked for. Unable to use the latest version I have installed. Is there a way to make VS only recognize one version?? – user2292759 Jun 17 '18 at 12:40
  • @user2292759, maybe [this](https://stackoverflow.com/questions/24022134/how-exactly-does-the-specific-version-property-of-an-assembly-reference-work-i) will be helpful. – George Alexandria Jun 17 '18 at 12:52

2 Answers2

3

Had the same problem with dynamically compiling assembly (.Net Core 3.1).

In code below:

public IEnumerable<object> GetMetadata()
{
    return _objects.Select(GetMetadata).ToList();
}

was required reference to System.Collections.

The type 'List<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Collections, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

But referencing to something like this

typeof(System.Collections.IList).Assembly

has returned location of System.Private.CoreLib.dll.

So

const string longName = "System.Collections, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

var systemCollectionsAssembly = Assembly.Load(longName);

provided reference.

2

I ended up resolving the issue by manually referencing the System.Collections dll it was asking for like so:

string longName = "System.Collections, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

Assembly assemCollec = Assembly.Load(longName);

MetadataReference[] references = new MetadataReference[]
{
    MetadataReference.CreateFromFile(assemCollec.Location),
    // Other Assemblies . . .

};

Hopefully this helps anyone else who runs into this issue.

user2292759
  • 159
  • 1
  • 9