2010-07-06 4 views
2

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

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» должен быть указан (но не для обоих).

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

ответ

9

Вы не указали свойство вывода в своей задаче. Вы должны использовать атрибут 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; 
    } 
} 
+1

Правильно, я также необходимо добавить mhenrixon

+1

Спасибо, я хотел бы дать вам больше очков для того! ;) – mhenrixon

+0

Добро пожаловать =) –