0

So, I am writing a code generator tool and I want to get the default namespace from an existing csproj that the user will have to specify. Essentially I want to be able to load the csproj from a path and get some configuration from it.

I also want to be able to get all existing projects from a solution, from which I would use the solution file from a path.

I've looked into code analyzers and believe that's the way to go, but I haven't found a single example of what I want to achieve so far.

I do not wish to give support to older format csproj, just the Microsoft.NET.Sdk format that came with VS2017.

Carlos Jimenez Bermudez
  • 1,070
  • 1
  • 14
  • 36
  • 2
    Is your tool something which could be written as a [Source generator](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/)? Then you don't have to worry about loading csproj files, etc – canton7 Jan 08 '21 at 16:31
  • It's a tool like the ef core reverse engineering scaffolder, but for repoDb and with zero dependencies on EF. I am querying the information_schema, generation basic entities and some other config code. But I don't want my users to have to specify a namespace to the tool. I'll look into Source generators. – Carlos Jimenez Bermudez Jan 08 '21 at 16:34
  • My idea is for it to be able to be run as a CLI that receives certain parameters, such as the db engine, the connection string and which csproj the files will end up in. – Carlos Jimenez Bermudez Jan 08 '21 at 16:38
  • Yeah, I think source generators are not a good fit for the kind of tool I am building. – Carlos Jimenez Bermudez Jan 08 '21 at 17:24
  • 1
    That's fine, but it's worth asking the question! It's probably easiest to load the sln / csproj into an `MSBuildWorkspace`, and use Roslyn to analyze it – canton7 Jan 08 '21 at 17:33
  • Thanks, that's exactly what I needed. – Carlos Jimenez Bermudez Jan 08 '21 at 17:56

1 Answers1

0

So the solution as stated in the comments was to use an MSBuildWorkspace.

My code looks something like this:

using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis;

public class ProjectLoader : IProjectLoader
{
    public string GetVSProjectDefaultNamespace(string projectPath)
    {
        var workspace = MSBuildWorkspace.Create();
        Project project;

        try
        {
            project = workspace.OpenProjectAsync(projectPath).Result;
        }
        catch(Exception e)
        {
            throw new Exception("The requested project failed to load. Make sure the path to the project file is correct.", e);
        }
            
        var defaultNamespace = project.DefaultNamespace ?? project.Name;
        
        return defaultNamespace;
    }
}

It's important to install the following nuget packages:

Microsoft.CodeAnalysis
Microsoft.CodeAnalysis.Workspaces.MSBuild

For the previous snippet to work.

Hope this helps anybody else!

Carlos Jimenez Bermudez
  • 1,070
  • 1
  • 14
  • 36