10

I have a situation where I want to copy the output assembly from one project into the output directory of my target application using MSBuild, without hard-coding paths in my MSBuild Copy task. Here's the scenario:

  • Project A - Web Application Project
  • Project B - Dal Interface Project
  • Project C - Dal Implementation Project

There is a Business layer too, but has no relevance for the MSBuild problem I'm looking to solve.

My business layer has a reference to my Dal.Interface project. My web project has a reference to the Business layer and as it stands, doing a build will pull the business layer and Dal.Interface projects into the output. So far, so good. Now in order for the web app to run, it needs the Dal implementation. I don't want the implementation referenced anywhere since I want to enforce coding to the interface and not having a reference means it won't show up in intellisense, etc.

So I figured I could handle this through the MSBuild copy operation as an AfterBuild task (I have the Dal Implementation setup to build when the web project builds, just not referenced). I don't want to hard code paths or anything else in the MSBuild params, so I'm trying to figure out how to reference the output of the Dal project from the Web Application Project's MSBuild file.

So based on the projects mentioned above this is what I want to see happen:

  1. Web app build is kicked off
  2. All required projects build (already configured, so this is done)
  3. MSBuild "AfterBuild" task kicks off and the output from Project C (Dal Implementation) is copied to the Bin directory of Project A (web app)

Part 3 is where I'm stuck.

I'm sure this can be done, I'm just not finding a good reference to help out. Thanks in advance for any help.

Andrew Van Slaars
  • 1,816
  • 1
  • 14
  • 20

2 Answers2

9

I have made this work, though I would love to find a cleaner solution that takes advanctage of the built-in parameters within MSBuild (like $(TargetDir), etc but to point at the project I want to grab the output for). Anyway, here is what I've done:

<Target Name="AfterBuild">
<Copy SourceFiles="$(SolutionDir)MyProject.Dal.Linq\bin\$(Configuration)\MyProject.Dal.Linq.dll" DestinationFolder="$(TargetDir)"/>
</Target>

I would love to see a cleaner solution, but this should do for now.

Andrew Van Slaars
  • 1,816
  • 1
  • 14
  • 20
  • I +1'd this ages ago. As you've suggested this isnt clean - obviously this breaks if the OutDir changes, e.g. when building with TeamBuild. (Just in case others see this and dont realise the shortcomings). See also http://stackoverflow.com/questions/2325598/determining-outputs-of-a-projectreference-in-msbuild/2325620#2325620 – Ruben Bartelink Feb 24 '10 at 11:41
  • See http://stackoverflow.com/questions/2325598/determining-outputs-of-a-projectreference-in-msbuild/2325620#2325620 for an example of a way of addressing the concern I mentioned – Ruben Bartelink Feb 24 '10 at 13:08
3

So, you want to have a reference, but not have it visible in VS. So you want it built if needed, and copied to output like any other Content file. Here's how you'd do it:

<Target Name="IncludeDALImplementation" BeforeTargets="AfterBuild">
  <MSBuild Projects="..\DalImplementation\DAL.csproj" BuildInParallel="$(BuildInParallel)" Targets="Build">
    <Output TaskParameter="TargetOutputs" ItemName="DalImplementationOutput" />
  </MSBuild>

  <ItemGroup>
    <Content Include="@(DalImplementationOutput)" />
  </ItemGroup>
</Target>
Jonathan
  • 6,939
  • 4
  • 44
  • 61
  • I'm getting this error: `The "Content" task was not found.` when compiling in Visual Studio – Thorarin Apr 30 '15 at 16:14
  • @Thorarin: Fixed code, sorry about that. Note that it's still untested – Jonathan May 03 '15 at 08:45
  • I made the same change and it worked. I needed to copy the dependencies as well as the output of the project itself though, so I had to change my approach a little. – Thorarin May 07 '15 at 05:33
  • Is it possible to get the TargetOutputs without actually building? – Macke May 02 '19 at 14:37
  • It might be. However, doesn't really make sense - the output folder is only created during build of the project, so not much you can do without it beforehand. – Jonathan May 05 '19 at 10:04