示例#1
0
        // In here, we're defining a class, foo_Task, derived from our DefinedTask class. This allows us to write the bulk of the code
        // in real C#, rather than attempting to build it here.
        // This means that we have Task <- DefinedTask <- foo_Task.
        // We also need a module and an assembly to hold the class, so we do that, too.
        protected override void ExecuteTask()
        {
            AssemblyName assemblyName = new AssemblyName();

            assemblyName.Name = _taskName + "_Assembly";

            AssemblyBuilder assemblyBuilder =
                AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(_taskName + "_Module");

            // Now we've got an assembly and a module for the task to live in, we can define the actual task class.
            TypeBuilder typeBuilder = moduleBuilder.DefineType(_taskName + "_Task", TypeAttributes.Public);

            typeBuilder.SetParent(typeof(DefinedTask));

            // It needs a [TaskName] attribute.
            ConstructorInfo taskNameAttributeConstructor =
                typeof(TaskNameAttribute).GetConstructor(new Type[] { typeof(string) });
            CustomAttributeBuilder taskNameAttributeBuilder =
                new CustomAttributeBuilder(taskNameAttributeConstructor, new object[] { _taskName });

            typeBuilder.SetCustomAttribute(taskNameAttributeBuilder);

            // We're done. Create it.
            Type taskType = typeBuilder.CreateType();

            // Stash the XML in our static. We'll need it in DefinedTask later.
            DefinedTaskDefinitions.Add(_taskName, XmlNode);

            // Hook that up into NAnt.
            TaskBuilder taskBuilder = new TaskBuilder(taskType.Assembly, taskType.FullName);

            TypeFactory.TaskBuilders.Add(taskBuilder);
        }
示例#2
0
        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);
                }
            }
        }