Search code examples
c#.net-corecode-generationroslyn

Is it possible to reference existing source files in C# Roslyn Code Generation?


So consider the case where I have a class ClassA inside of the project that is currently being generated into:

public class ClassA
{
    public ClassA(int a)
    {
        A = a;
    }

    public int A { get; set; }
}

Let's say that I wanted to automatically create an extension method for ClassA, something like:

public static class ClassAExtensions
{
    public static ClassA Double(this ClassA classA)
    {
        return new ClassA(classA.A * 2);
    }
}

When trying to create this source code using the new source code generators, the compilation can't seem to find ClassA. I've tried adding the namespace of ClassA into the generated document and setting the namespace of the generated extension method class to the namespace directly to that of ClassA, but neither seem to be able to see it:

The type of namespace 'ClassA' does not exist in the namespace 'ClassANamespace' (are you missing an assembly reference?)

So the final questions are:

  • Is there some trick to making the code generation compiler be able to see my non-generated code?
  • Is this even possible right now?
  • Is there a workaround to get something like this to work?

Many of the samples provided declare the class being modified partial, but I don't particularly like this for what I'm trying to do.

I've also looked into adding an assembly reference, though my understanding was that the code being generated should be included and compiled alongside the existing code. Also, if this code is being compiled before my "production" code, then adding an assembly reference would not be possible and/or this would create a circular reference.


Solution

  • Files added in a source generator act like regular files from the perspective of the rest of the language rules so yes you can absolutely reference classes in the user's code as long as you're qualifying them correctly. It sounds like you have a bug; if there's still a specific problem you may want to try creating a project that contains both the input file and also the source generated output; you should see the same error and then can figure out what's up.