0

I am trying to include a shared class between 2 projects, but i can't seem to find out how add them to the project visual studio code, so i can use them. I hope this image helps explain I am trying to ask

How the folder structure would look

user629283
  • 329
  • 1
  • 8
  • 23
  • Create project C, put class there, add dependency on project C by project A and project B – zaitsman Aug 11 '20 at 02:59
  • Why are you using visual studio code when their is a community edition to visual studio, that gives you a standard IDE experience – TheGeneral Aug 11 '20 at 03:32
  • @TheGeneral I started the project in visual studio code and i like the "dotnet watch" console since it will compile for me as i save. – user629283 Aug 11 '20 at 03:35
  • OP, are you talking about shared *source code*? Or are you just trying to share an assembly and set a reference? (For the most part, c# developers don't share source code between projects like a c++ developer might) – John Wu Aug 11 '20 at 03:41
  • @JohnWu shared source. – user629283 Aug 11 '20 at 04:10

4 Answers4

2

I'm not sure for what reason you'd want to have the source code shared between projects instead of the resulting compiled assembly, but given this directory structure...

  • ProjectA\
    • ProjectA.csproj
    • Program.cs
  • ProjectB\
    • ProjectB.csproj
    • Program.cs
  • Shared\
    • Shared.cs

...I was able to use a shared code file (Shared\Shared.cs) like this...

namespace Shared
{
    internal static class Example
    {
        internal static void SayHello()
        {
            string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

            System.Console.WriteLine($"Hello, World!  This is {assemblyName}.");
        }
    }
}

...from console application code files (ProjectA\Program.cs and ProjectB\Program.cs) like this...

namespace ProjectA // or ProjectB
{
    class Program
    {
        static void Main()
        {
            Shared.Example.SayHello();
        }
    }
}

...by modifying the default console application project files (ProjectA\ProjectA.csproj and ProjectB\ProjectB.csproj) like this to include all .cs files from the Shared\ directory...

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="..\Shared\*.cs" />
  </ItemGroup>
</Project>

...which yielded these results when run from the base directory...

PS> dotnet run --project ProjectA
Hello, World!  This is ProjectA.
PS> dotnet run --project ProjectB
Hello, World!  This is ProjectB.

Interestingly, I ran the dotnet msbuild command like this...

dotnet msbuild ProjectA -preprocess:fullproject.xml

...to produce a file showing the behind-the-scenes definitions MSBuild would use, and it included a comment describing this same hierarchy with even the same sample names I used...

<!-- WARNING: This pattern is there to ignore folders such as .git and .vs, but it will also match items included with a
      relative path outside the project folder (for example "..\Shared\Shared.cs").  So be sure only to apply it to items
      that are in the project folder. -->
<DefaultExcludesInProjectFolder>$(DefaultItemExcludesInProjectFolder);**/.*/**</DefaultExcludesInProjectFolder>

Maybe not a good solution, but another solution would be to use symlinks/hardlinks/junctions to include the shared code file(s)/directory directly in each project like this...

  • ProjectA\
    • ProjectA.csproj
    • Program.cs
    • Shared.cs..\Shared\Shared.cs
  • ProjectB\
    • ProjectB.csproj
    • Program.cs
    • Shared.cs..\Shared\Shared.cs
  • Shared\
    • Shared.cs

...or this...

  • ProjectA\
    • ProjectA.csproj
    • Program.cs
    • Shared\..\Shared\
      • Shared.cs
  • ProjectB\
    • ProjectB.csproj
    • Program.cs
    • Shared\..\Shared\
      • Shared.cs
  • Shared\
    • Shared.cs

...although I could see that causing some headaches with source control.

In all of the above examples I used a convenient base directory and relative paths, but there's no reason you couldn't use absolute paths, if needed.

Lance U. Matthews
  • 15,725
  • 6
  • 48
  • 68
  • I got it working last night and i realise that you need to create another project and include the csproj across to the project csproj file you wish to share it with. – user629283 Aug 13 '20 at 04:34
  • In the `Shared` code directory I demonstrate above I did not have to create a project file. I'm not sure what you mean, or how you would include one project in another other than the usual way of adding it as a reference, which copies the build output from one to another. – Lance U. Matthews Aug 13 '20 at 05:01
  • I have tested your demonstration, it worked perfectly, but i decided to include csproj because i can keep the nuget packages centralize in that folder. Thanks for your reply. – user629283 Aug 13 '20 at 08:54
  • The reason that OP may not have wanted to use a DLL is possibly because it causes more deployment complexity and also obfuscation is a problem since all methods need to be made public. Assuming more than 1 source file is involved, I have found creating a DLL is the best solution as opposed to using a Shared Project (which are troublesome to design). When you have your DLL, you can use an obfuscation tool to merge the assembly and internalize methods. Now you have the best of both worlds - your code can be obfuscated and is embedded within the 1 application. – Simple Guy Sep 27 '21 at 23:19
0

Create your ProjectA and ProjectB as you would normally do. Then create a shared project, say CommonProject. Once the shared project is referenced into the ProjectA and ProjectB, you should be able to access all the shared classes from all the referenced projects. Also you can include conditional compilations symbols within the class to suit the class definition per project.

zafar
  • 1,965
  • 1
  • 15
  • 14
0

I think that first you should create an .NET Standard Class Library Project and reference it like this: Reference image

  • Then you should use the CLI. I got a link that may help you. https://stackoverflow.com/questions/49805204/adding-reference-to-another-project-from-visual-studio-code#:~:text=Right%20click%20on%20project%20%2D%2D,reference%20project%20from%20the%20list.&text=In%20visual%20studio%2C%20in%20the,click%20and%20choose%20%22Add%22. – Gustavo Gavancho Aug 11 '20 at 03:35
0

For .NET Core & SDK style projects

Add Directory.Build.props to solution folder (ie- a parent folder of both projects):

<Project>  
    <PropertyGroup>
        <CoreCompileDependsOn>InitGlobal;$(CoreCompileDependsOn)</CoreCompileDependsOn>
    </PropertyGroup>
</Project>

Add Directory.Build.targets to solution folder (ie- a parent folder of both projects):

<Project>  
    <Target Name="InitGlobal" >
        <ItemGroup>
            <Compile Include="$(MSBuildThisFileDirectory)\Global\*.cs" />
        </ItemGroup>
    </Target>
</Project>

Finally

Add the shared/common class file(s) to \Global folder (relative to the Directory.Build.* files above). Careful that any dependencies used are included in each project, or that you add the dependencies in the Directory.Build.props.

Note - the global files will be included in the Build and the IntelliSense, but not visible in the solution. You can make them show as linked classes, by removing the element from the .targets and and putting it in the .props file

Peter
  • 971
  • 11
  • 12