/// <summary> /// Scans a given <see cref="Type" /> for tasks. /// </summary> /// <param name="extensionAssembly">The <see cref="ExtensionAssembly" /> containing the <see cref="Type" /> to scan.</param> /// <param name="type">The <see cref="Type" /> to scan.</param> /// <param name="task">The <see cref="Task" /> which will be used to output messages to the build log.</param> /// <returns> /// <see langword="true" /> if <paramref name="type" /> represents a /// <see cref="Task" />; otherwise, <see langword="false" />. /// </returns> private static bool ScanTypeForTasks(ExtensionAssembly extensionAssembly, Type type, Task task) { try { TaskNameAttribute taskNameAttribute = (TaskNameAttribute) Attribute.GetCustomAttribute(type, typeof(TaskNameAttribute)); if (type.IsSubclassOf(typeof(Task)) && !type.IsAbstract && taskNameAttribute != null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_CreatingTaskBuilder"), type.Name)); TaskBuilder tb = new TaskBuilder(extensionAssembly, type.FullName); if (TaskBuilders[tb.TaskName] == null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_AddingTask"), tb.TaskName, GetAssemblyLocation(tb.Assembly), tb.ClassName)); TaskBuilders.Add(tb); } // specified type represents a task return true; } else { // specified type does not represent valid task return false; } } catch { task.Log(Level.Error, "Failure scanning \"{0}\" for tasks.", type.AssemblyQualifiedName); throw; } }
/// <summary> /// Scans a given <see cref="Type" /> for tasks. /// </summary> /// <param name="type">The <see cref="Type" /> to scan.</param> /// <param name="task">The <see cref="Task" /> which will be used to output messages to the build log.</param> /// <returns> /// <see langword="true" /> if <paramref name="type" /> represents a /// <see cref="Task" />; otherwise, <see langword="false" />. /// </returns> private static bool ScanTypeForTasks(Type type, Task task) { try { TaskNameAttribute taskNameAttribute = (TaskNameAttribute) Attribute.GetCustomAttribute(type, typeof(TaskNameAttribute)); if (type.IsSubclassOf(typeof(Task)) && !type.IsAbstract && taskNameAttribute != null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_CreatingTaskBuilder"), type.Name)); TaskBuilder tb = new TaskBuilder(type.Assembly, type.FullName); if (TaskBuilders[tb.TaskName] == null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_AddingTask"), tb.TaskName, GetAssemblyLocation(tb.Assembly), tb.ClassName)); TaskBuilders.Add(tb); foreach (WeakReference wr in _projects) { if (!wr.IsAlive) { task.Log(Level.Debug, "WeakReference for project is dead."); continue; } Project p = wr.Target as Project; if (p == null) { task.Log(Level.Debug, "WeakReference is not a" + " project! This should not be possible."); continue; } UpdateProjectWithBuilder(p, tb); } } // specified type represents a task return(true); } else { // specified type does not represent valid task return(false); } } catch { task.Log(Level.Error, "Failure scanning \"{0}\" for tasks.", type.AssemblyQualifiedName); throw; } }
/// <summary> /// Creates a new instance of the <see cref="TaskBuilder" /> class /// for the specified task class in the assembly specified. /// </summary> /// <param name="className">The class representing the task.</param> /// <param name="assemblyFileName">The assembly containing the task.</param>/// public TaskBuilder(string className, string assemblyFileName) { _className = className; _assemblyFileName = assemblyFileName; // determine from which assembly the task will be created Assembly assembly = GetAssembly(); // get task name from attribute TaskNameAttribute taskNameAttribute = (TaskNameAttribute) Attribute.GetCustomAttribute(assembly.GetType(ClassName), typeof(TaskNameAttribute)); _taskName = taskNameAttribute.Name; }
protected override void ExecuteTask() { Log(Level.Info, "Executing defined task."); // When you call a defined task, you can define any XML attributes that you want. // We take those, and convert them to properties called "this.whatever". This makes // them available to the enclosed XML with predictable names. foreach (XmlAttribute attr in XmlNode.Attributes) { string thisPropertyName = "this." + attr.Name; string thisPropertyValue = Properties.ExpandProperties(attr.Value, Location); Properties.Add(thisPropertyName, thisPropertyValue); } // DefineTask created a class derived from DefinedTask. Pick up the [TaskName] attribute from that derived class. TaskNameAttribute taskNameAttribute = (TaskNameAttribute)Attribute.GetCustomAttribute(GetType(), typeof(TaskNameAttribute)); // We stashed the enclosed XML node in the DefintedTaskDefinitions global collection; pick it up now. XmlNode originalDefinitionNode = DefinedTaskDefinitions.Find(taskNameAttribute.Name); // NAnt conveniently already has a way to nest tasks: TaskContainer. This is how <if>, <foreach/do>, etc., work. // We need to define our own derived class to get access to some of the protected properties. DefinedTaskContainer containedTasks = DefinedTaskContainer.Create(this, originalDefinitionNode); try { containedTasks.Execute(); } finally { foreach (XmlAttribute attr in XmlNode.Attributes) { Properties.Remove("this." + attr.Name); } } }