MSBuild, настраиваемая задача для запуска настраиваемого инструмента для создания классов для модели linq to sql?

У меня такой сценарий. Мы используем хранимые процедуры для доступа к базе данных, и мы используем LiNQ 2 SQL для генерации классов, а именно мы используем Unplugged LINQ to SQL Generator для этого. Он был запущен как специальный инструмент, но различать сгенерированные классы - большая головная боль. Мы хотели бы автоматически сгенерировать классы, но исключить их из контроля версий, поэтому я поставил задачу создать задачу msbuild. Нашел этот пост и этот пост, но я не могу решить эту проблему один сам. Я добавил код, задача выглядит следующим образом:

public class GenerateDesignerDC : Task
{
    public ITaskItem[] InputFiles { get; set; }
    public ITaskItem[] OutputFiles { get; set; }

    public override bool Execute()
    {
        var generatedFileNames = new List<string>();
        foreach (var task in InputFiles)
        {

            string inputFileName = task.ItemSpec;
            string outputFileName = Path.ChangeExtension(inputFileName, ".Designer.cs");
            string result;

            // Build code string
            var generator = new ULinqCodeGenerator("CSharp");
            string fileContent;
            using (FileStream fs = File.OpenRead(inputFileName))
            using (StreamReader rd = new StreamReader(fs))
            {
                fileContent = rd.ReadToEnd();
            }

            using (var destination = new FileStream(outputFileName, FileMode.Create))
            {
                byte[] bytes = Encoding.UTF8.GetBytes(generator.BuildCode(inputFileName, fileContent));
                destination.Write(bytes, 0, bytes.Length);
            }
            generatedFileNames.Add(outputFileName);
        }

        OutputFiles = generatedFileNames.Select(name => new TaskItem(name)).ToArray();

        return true;
    }
}

Теперь я пытаюсь добавить для этого настраиваемую цель под названием custom.target.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <CoreCompileDependsOn>$(CoreCompileDependsOn);GenerateToolOutput</CoreCompileDependsOn>
    </PropertyGroup>
    <UsingTask TaskName="BuildTasks.GenerateDesignerDC" AssemblyFile="BuildTasks.dll" />
    <Target Name="GenerateToolOutput" Inputs="@(dbml)" Outputs="@(dbml->'$(IntermediateOutputPath)%(FileName).designer.cs')">
        <GenerateDesignerDC InputFiles="@(dbml)" OutputFiles="@(dbml->'$(IntermediateOutputPath)%(FileName).designer.cs')">
            <Output ItemGroup="Compile" TaskParameter="OutputFiles" />
        </GenerateDesignerDC>
    </Target>
</Project>

Я также добавляю необходимые ItemGroups в файл проекта следующим образом:

<ItemGroup>
    <AvailableItemName Include="dbml" />
</ItemGroup>
<ItemGroup>
    <Compile Include="@(dbml)" />
</ItemGroup>

И, наконец, я добавляю в проект следующие файлы:

<dbml Include="DAL\SettingsDC.dbml">
    <SubType>Designer</SubType>
    <Generator>ULinqToSQLGenerator</Generator>
    <LastGenOutput>SettingsDC.designer.cs</LastGenOutput>
</dbml>

Это вызывает сообщение об ошибке

Задача «GenerateDesignerDC» имеет недопустимую спецификацию вывода. Атрибут «TaskParameter» является обязательным, и необходимо указать атрибут «ItemName» или «PropertyName» (но не оба сразу).

Что мне нужно сделать, чтобы это сработало?


person mhenrixon    schedule 06.07.2010    source источник


Ответы (1)


Вы не объявили свойство вывода в своей задаче. Вы должны использовать атрибут Output в свойстве OutputFiles.

public class GenerateDesignerDC : Task
{
    [Required]
    public ITaskItem[] InputFiles { get; set; }

    [Output]
    public ITaskItem[] OutputFiles { get; set; }

    public override bool Execute()
    {
        var generatedFileNames = new List<string>();
        foreach (var task in InputFiles)
        {

            string inputFileName = task.ItemSpec;
            string outputFileName = Path.ChangeExtension(inputFileName, ".Designer.cs");
            string result;

            // Build code string
            var generator = new ULinqCodeGenerator("CSharp");
            string fileContent;
            using (FileStream fs = File.OpenRead(inputFileName))
            using (StreamReader rd = new StreamReader(fs))
            {
                fileContent = rd.ReadToEnd();
            }

            using (var destination = new FileStream(outputFileName, FileMode.Create))
            {
                byte[] bytes = Encoding.UTF8.GetBytes(generator.BuildCode(inputFileName, fileContent));
                destination.Write(bytes, 0, bytes.Length);
            }
            generatedFileNames.Add(outputFileName);
        }

        OutputFiles = generatedFileNames.Select(name => new TaskItem(name)).ToArray();

        return true;
    }
}
person Julien Hoarau    schedule 07.07.2010
comment
Правильно, мне также нужно было добавить ‹Output TaskParameter = OutputFiles Propertyname = OutputFiles /› - person mhenrixon; 07.07.2010