Подтвердить что ты не робот

В чем разница между "DependsOnTargets" и "AfterTargets"?

Я не могу различить эти два. Пожалуйста, помогите!

4b9b3361

Ответ 1

DependsOnTargets

Определяет цели, которые должен быть выполнен до, цель может быть выполнена.

<Target Name="DependsOn" DependsOnTargets="DependencyTarget1;DependencyTarget2">
  <Message Text="Target : DependsOn"/>
</Target>

<Target Name="DependencyTarget2">
  <Message Text="Target : DependencyTarget2"/>
</Target> 

<Target Name="DependencyTarget1">
  <Message Text="Target : DependencyTarget1"/>
</Target> 

Output
> Target : DependencyTarget1
> Target : DependencyTarget2
> Target : DependsOn

BeforeTargets и AfterTargets (доступно только в MSBuild 4)

Указывает, что цель должна быть работать до или после указанного целевого объекта или целей.

<Target Name="BeforeAndAfter">
  <Message Text="Target : BeforeAndAfter"/>
</Target>

<!-- BeforeTarget1 will run BEFORE target "BeforeAndAfter" -->
<Target Name="BeforeTarget" BeforeTargets="BeforeAndAfter">
  <Message Text="BeforeTarget run before : BeforeAndAfter"/>
</Target> 

<!-- BeforeTarget1 will run AFTER target "BeforeAndAfter" -->
<Target Name="AfterTarget" AfterTargets="BeforeAndAfter">
  <Message Text="AfterTarget run after : BeforeAndAfter"/>
</Target> 

Output
> BeforeTarget run before : BeforeAndAfter
> Target : BeforeAndAfter
> AfterTarget run after : BeforeAndAfter
  • Если у вас есть цели с множественными значениями, которые должны выполняться до или после одного и того же указанного объекта, они будут выполняться в порядке объявления:

    <Target Name="BeforeAndAfter">
      <Message Text="Target : BeforeAndAfter"/>
    </Target>
    
    <!-- 
       BOTH BeforeTarget1 and BeforeTarget2 should run before target "BeforeAndAfter"
    -->
    <Target Name="BeforeTarget1" BeforeTargets="BeforeAndAfter">
      <Message Text="BeforeTarget1 run before : BeforeAndAfter"/>
    </Target> 
    
    <Target Name="BeforeTarget2" BeforeTargets="BeforeAndAfter">
      <Message Text="BeforeTarget2 run before : BeforeAndAfter"/>
    </Target> 
    

BeforeTargets и AfterTargets могут использоваться для расширения существующего процесса сборки.

Например, с помощью этих атрибутов вы можете легко выполнить цель до CoreCompile (определяется в Microsoft.CSharp.targets). Без этого вам придется переопределить свойство CoreCompileDependsOn.

Без AfterTargets у вас нет возможности легко выполнить цель после другого, если не определена точка расширения (CallTarget в конце цели с свойством, которое вы можете переопределить)

Зависит от заказов, ордеров BeforeTargets и AfterTargets?

Когда DependsOnTargets, BeforeTargets и AfterTargets используются на одной и той же цели, порядок выполнения:

  • DependsOnTargets
  • BeforeTargets
  • Цель
  • AfterTargets

    <Target Name="MainTarget" DependsOnTargets="DefaultDependsOn">
      <Message Text="Target : MainTarget"/>
    </Target>
    
    <Target Name="DefaultDependsOn">
      <Message Text="Target : DefaultDependsOn"/>
    </Target>
    
    <Target Name="DefaultBeforeTarget" BeforeTargets="MainTarget">
      <Message Text="Target : DefaultBeforeTarget"/>
    </Target>
    
    <Target Name="DefaultAfterTarget" AfterTargets="MainTarget">
      <Message Text="Target : DefaultAfterTarget"/>
    </Target> 
    
    Output
    > Target : DefaultDependsOn
    > Target : DefaultBeforeTarget
    > Target : MainTarget
    > Target : DefaultAfterTarget
    

Ответ 2

Я думаю, что ответ намного проще. Эффект DependsOnTargets и AfterTargets по существу тот же. Причина BeforeTargets и AfterTargets (из документации Microsoft):

Это позволяет автору проекта расширить существующий набор целей без изменяя их напрямую.

Итак, если у вас есть существующая цель B, и вы хотите добавить новую цель A, которая должна выполнить сначала, у вас есть два варианта:

  • Измените цель B следующим образом: DependsOnTargets = "A".

  • Измените цель A следующим образом: BeforeTargets = "B".

Если вы не можете изменить B (например, существующую целевую Microsoft), это когда вам нужно BeforeTargets.

Ответ 3

В то время как другие ответы, предоставленные ранее, верны, я думаю, что они не упоминали о том, что я считаю основным преимуществом AfterTargets более DependsOnTargets.

DependsOnTargets существует с самого начала MSBuild. Проблема с DependsOnTargets заключается в том, что для целевого автора требуется явно разрешить расширяемость. Это делается путем определения свойства, которое используется как значение DependsOnTargets, следующим образом:

<PropertyGroup>
   <SomeTargetDependsOnTargets>
     Dependency1;Dependency2
   </SomeTargetDependsOnTargets>
</PropertyGroup>

<Target Name="SomeTarget" DependsOnTargets="$(SomeTargetDependsOnTargets)">
 ...
</Target>

Затем вы можете добавить зависимость, изменив свойство SomeTargetDependsOnTargets следующим образом:

<SomeTargetDependsOnTargets>
    $(SomeTargetDependsOnTargets);Dependency3
</SomeTargetDependsOnTargets>

Проблема с этим дизайном заключается в том, что если автор просто ввел Dependency1;Dependency2 вместо того, чтобы извлечь его в свойство, не было бы способа изменить его внешнее, чтобы разрешить настройку.

AfterTargets, с другой стороны, не требует, чтобы исходный автор цели явно выделил значение DependsOnTargets в качестве свойства, позволяющего расширяемость.

Ответ 4

DependsOnTarget - предположим, что у вас есть две задачи: 1 - Build Project, 2 - копирование всего содержимого. Вы можете начать сборку, выполнив задачу 2, а затем в объявлении задачи определите ее зависимости. Поэтому, если вы определите, что задача 2 зависит от задачи 1, процесс сборки запустится и выполнит задачу 1, а затем 2.

AfterTargets - намного проще означает только задачи, которые выполняются после других целей. Итак, возьмем пример сверху - после выполнения задачи 1 - выполнить проект выполнить задачу 2.

Я надеюсь, что это поможет

Ответ 5

Более кратко из этой проблемы GitHub в Документах Microsoft:

<Target Name="x" DependsOnTargets="y" /> означает:

Если что-то хочет запустить x, сначала нужно запустить y.

<Target Name="a" AfterTargets="b" /> означает:

Если что-то запускает b, тогда запустите a после него.