asp.netmsbuildreinforced-typings

Is it possible to build two MSBuild projects which are partially dependent on each other?


I have two MSBuild projects which are partially dependent on each other.

Project A, the backend, is an ASP.NET project which exports TypeScript declarations using the Reinforced.Typings framework. The types need to be the first step in the build process.

Project B, the frontend, is a React project built using vite and an .esproj file. The frontend needs the types built from the backend in order to build properly. Building the frontend need to be the second step in the build process.

Finally the resulting build files of Project B needs to be copied over to Project A's wwwroot, in order to be served through the ASP.NET web server.

I have tried ProjectReferences, but since the two project depend on each other, it creates a circular reference error. I have also managed to get it working by building everything in Project A's .csproj file, including copying the generated types out of Project A into Project B. However, I and the rest of the team consider this a dirty solution, since it makes the build step impure. I have also tried using the RtAdditionalAssembly feature of Reinforced.Typings, but it doesn't work since it requires the full assemblies from Project A to be built before Project B can use the types.

I think this could be solved by building one target of Project A first, then building Project B, and finally running the PostBuild target of Project A. I have however not been able to find any information on how to achieve this.

Any help would be greatly appreciated, thanks in advance!


Solution

  • Two projects cannot be dependent on each other. As you noted regarding ProjectReference, this is a circular reference.

    However, there are some patterns I can suggest. One, or a combination, may help.

    Add a Utility Target

    You can define custom targets in a project that are not in the target chain when a build is performed. The MSBuild task can be used to invoke a specific target on a specific project from another project.

    A tricky part of this approach is that a utility target can't depend on the build target (or on any specific state of the project) because that would create a circular reference.

    Add a Utility Project

    Add a new project that uses the Microsoft.Build.NoTargets SDK to create a utility project.

    There are a couple of ways the utility project could be used, but one possible way is to have the utility project depend on projects A and B and to collect the files for the wwwroot folder that will be published to the web server.

    Create a Solution Shared Folder

    Conventionally the solution folder contains the project folders. From within a project, you can search up the folder hierarchy for a specific file. e.g. you might search for the .sln file. Given the solution folder, you might define a common shared folder that each project can copy files to.

    The logic to find the shared folder can be put in a Directory.Build.targets file and used by all projects.

    The wwwroot folder might be expected to be built up in the shared folder as each project is built.