Breaking up the project file this way allows for sections of the file to be changed without affecting others. For example, one way of building a project with resources is to place the GenerateResource and Csc tasks in the same target, for example:
|
<Target Name="Build">
<GenerateResource
Sources="alpha.resx; beta.txt"
<Output
TaskParameter="OutputResources"
ItemName="Resources"/>
</GenerateResource>
<Csc
Sources="hello.cs"
Resources="@(Resources)"
OutputAssembly="hello.exe"/>
</Target>
|
Using this approach, the project builds as required, but the target is becoming large and inflexible. If you later wanted to add other tasks to run between GenerateResource and Csc, putting them all in one target would make the project file very difficult to read. In addition, authoring such large targets with so many tasks makes it difficult to perform good incremental builds — builds in which only those targets that have not been built before or targets that are out of date are rebuilt. Large targets also prevent you from running targets to perform specific tasks. In the example above, there is no way to generate resources without compiling.
A better way of authoring a project file is to use multiple targets and explicitly express dependencies between them. This approach also gives you the ability to run any of the targets separately and perform a smaller set of tasks rather than running a long list of tasks in one target every time you build. In this example, each task is in a separate target and the DependsOnTargets attribute specifies that the Resources target must run before the Build target can run.
|
<Target Name="Resources">
<GenerateResource
Sources="alpha.resx; beta.txt"
<Output
TaskParameter="OutputResources"
ItemName="Resources"/>
</GenerateResource>
</Target>
<Target Name="Build" DependsOnTargets="Resources">
<Csc
Sources="hello.cs"
Resources="@(Resources)"
OutputAssembly="hello.exe"/>
</Target>
|