12

I have a class library that is referenced by many other web application projects. It has many settings in its app.config that I wish to use in all of the referencing web projects. When the class library is built, it copies the app.config to its own bin folder as <assembly.name>.dll.config.

How do I ensure that <assembly.name>.dll.config is copied to the bin folder of each of my referencing web application projects?

  • Visual Studio / MSBuild does not seem to do this by default.
  • Changing Copy to Output Directory or Build Action (in any combination) does not work.
  • SlowCheetah VS extension appears to do what I want as an unintended side-effect of its config transform process, but I want to do this without any 3rd-party extensions.

As an aside: It's impractical to manually put all of this config in each of the web application projects. I can read the file by looking for <assembly.name>.dll.config in the bin folder, and extract the settings from there. I can already do this, so that's not an issue - I just need to ensure the file is going to be there for reading

Community
  • 1
  • 1
theyetiman
  • 8,514
  • 2
  • 32
  • 41

2 Answers2

14

This can be achieved without 3rd-party tools by adding the following to the class library's project file, assembly.name.csproj:

// Find this <Import> element for Microsoft.CSharp.targets
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
// Add this <ItemGroup> element immediately after
<ItemGroup>
    <Content Include="app.config">
        <Link>$(TargetName).dll.config</Link>
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
</ItemGroup>

This causes the app.config to be copied to whichever project is referencing it as <assembly.name>.dll.config. It's good because you only need to configure the one .csproj file and the effect cascades out to all referencing projects.

theyetiman
  • 8,514
  • 2
  • 32
  • 41
  • 1
    I'm trying to get this to work with WebSite Projects but it doesn't copy the *.dll.config file over. – CincauHangus May 31 '16 at 03:34
  • 2
    Awesome! I had WinFormsApp with reference to ConsoleApp and I was required to copy ConsoleApp.exe.config file to WinFormsApp output folder. I slightly modified the code above `$(TargetName).exe.config`. (`dll` changed to `exe`) – opewix Jun 15 '16 at 19:50
  • @cincua I'm not sure about Website projects, sorry. Works for Web Application project or WinFormsApp it would seem. Maybe you could try creating a Web Application project to check you've not done something wrong and confirm it's the Web Site project that's the culprit? – theyetiman Jun 16 '16 at 16:52
  • I can't find anywhere in the MSBuild schema reference... drilling down, only lists as its child node (which of course isn't correct). Where did you find this solution? – James King Jan 19 '17 at 16:21
  • @JamesKing `Item` is a generic term which can actually be called anything. The docs don't quite explain it, but you can see from their examples in the following link that any element name goes: https://msdn.microsoft.com/en-us/library/ms171453.aspx E.g. you can have `CSFile`, `Compile` or `Content` or even `Stuff`. I believe the convention used by Visual Studio is to have `Compile` for things that are to be compiled and `Content` for things that are to be deployed by not compiled, judging from my own `.csproj` files. – theyetiman Jan 19 '17 at 16:48
  • That was what I was beginning to assume. Some more digging came up with a list of the well-known items (though ironically, the documentation for .. seems incorrect :P) Thanks!! https://msdn.microsoft.com/en-us/library/bb629388.aspx – James King Jan 19 '17 at 17:22
  • 1
    This works great! One side note: Although this already works by replacing the existing element for `app.config`, the configuration file will not be visible any more in the Solution Explorer. So I left the original element and just added another one with `Link` and `CopyToOutputDirectory` child elements. – CodeFox Apr 07 '17 at 13:51
  • 1
    I ended up with the following content for the `Link` element which works equally for `exe` and `dll` assemblies: `$(TargetFileName).config` – CodeFox Apr 07 '17 at 13:54
4

Visual Studio 2015 and earlier

For Visual Studio 2015, I am using the solution of @theyetiman (see this answer):

<ItemGroup>
  <None Include="app.config" />
</ItemGroup>
<ItemGroup>
  <None Include="app.config">
    <Link>$(TargetFileName).config</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

(The import of Microsoft.CSharp.targets was already present.)

Visual Studio 2017

During my experiments, Visual Studio 2017 seems to handle configuration files as expected out of the box. No manual modification of the project file is needed.

Community
  • 1
  • 1
CodeFox
  • 3,321
  • 1
  • 29
  • 41