2017-09-16 2 views
1

Lorsque le code suivant est exécuté dans MSBuild, j'obtiens une exception InvalidOperationException. Je me demandais pourquoi c'est?Pourquoi ne puis-je pas utiliser MsBuild TaskLoggingHelper dans un constructeur de tâches personnalisé?

public class SimpleTask3 : Task 
{ 
    public SimpleTask3() 
    { 
     Log.LogMessage(MessageImportance.High, "A MESSAGE"); 
    } 


    public override bool Execute() 
    { 
     return true; 
    } 
} 

L'erreur complète reçue est la suivante

error MSB4061: The "SimpleTask3" task could not be instantiated from ...ConsoleApplication1.dll 
error MSB4061: System.InvalidOperationException: Task attempted to log before it was initialized. Message was: A MESSAGE 
error MSB4061: at Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(String resourceName, Object[] args) 
error MSB4061: at Microsoft.Build.Utilities.TaskLoggingHelper.LogMessage(MessageImportance importance, String message, Object[] messageArgs) 
error MSB4061: at SimpleTask3.SimpleTask3..ctor() in SimpleTask.cs:line 10 
error MSB4060: The "SimpleTask3" task hasbeen declared or used incorrectly, or failed during construction. Check the spelling of the task name and the assembly name. 

Répondre

0

instances TaskLoggingHelper via BuildEngine.LogMessageEvent connecter afin qu'ils exigent cette instance BuildEngine avant de pouvoir être utilisés. De l'source code:

// If BuildEngine is null, task attempted to log before it was set on it, 
// presumably in its constructor. This is not allowed, and all 
// we can do is throw. 
if (BuildEngine == null) 
{ 
    ErrorUtilities.ThrowInvalidOperation("LoggingBeforeTaskInitialization", e.Message); 
} 

Les attaquants de propriété BuildEngine à _taskInstance.BuildEngine et _taskInstance est la tâche qui a créé le TaskLoggingHelper. Un groupe (à partir de laquelle vous dérivez directement) le fait dans son constructeur:

protected Task() 
{ 
    _log = new TaskLoggingHelper(this); 
} 

donc à ce moment _taskInstance.BuildEngine est encore nulle; il doit se mettre onze part. Comment et pourquoi est fondamentalement hors de portée pour cette réponse, car il ne vous aide pas: vous ne pouvez pas vous connecter au constructeur et il n'y a rien que vous pouvez changer à ce sujet ..

+0

Merci pour votre explication. Pourriez-vous expliquer le comment et pourquoi? Je comprends que cela ne m'aide pas mais je demandais plus par intérêt. Merci encore. –

+0

Je ne sais pas vraiment pourquoi cela est fait comme ça n'est pas expliqué dans le code mais une raison possible est que le constructeur reste simple pour que vous puissiez écrire votre constructeur sans paramètre sans avoir à passer des arguments à la classe de base constructeur, et le reste du code prend soin de configurer le BuildEngine sans que vous ayez à vous en soucier. Ce qui est fait ici: https://github.com/Microsoft/msbuild/blob/master/src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs#L369 – stijn