Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
RoslynCodeTaskFactory A platformfüggetlen Roslyn-fordítók használatával memóriabeli feladatszerelvényeket hoz létre beágyazott feladatként való használatra.
RoslynCodeTaskFactory a feladatok a .NET Standardot célozzák, és a .NET-keretrendszeren és a .NET Core-futtatókörnyezeteken, valamint más platformokon, például Linuxon és macOS-en is használhatók.
Megjegyzés:
A RoslynCodeTaskFactory csak az MSBuild 15.8-ban és újabb verziókban érhető el. Az MSBuild verziók a Visual Studio verzióit követik, így a RoslynCodeTaskFactory a Visual Studio 2017 15.8-s és újabb verzióiban érhető el.
Beágyazott feladat felépítése a RoslynCodeTaskFactory használatával
RoslynCodeTaskFactory a beágyazott tevékenységek deklarálása az UsingTask elem használatával történik. A beágyazott tevékenység és az UsingTask azt tartalmazó elem általában egy .targets fájlban van, és szükség szerint importálva van más projektfájlokba. Íme egy alapszintű beágyazott feladat. Figyelje meg, hogy nem csinál semmit.
<Project>
<!-- This simple inline task does nothing. -->
<UsingTask
TaskName="DoNothing"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup />
<Task>
<Reference Include="" />
<Using Namespace="" />
<Code Type="Fragment" Language="cs">
</Code>
</Task>
</UsingTask>
</Project>
A UsingTask példában szereplő elem három attribútummal rendelkezik, amelyek a feladatot és az azt fordító beágyazott feladat-előállítót írják le.
Ebben
TaskNameaz esetben az attribútum neve a tevékenység.DoNothingAz
TaskFactoryattribútum a beágyazott feladat-előállítót megvalósító osztálynak nevezi el.Az
AssemblyFileattribútum a beágyazott feladat-előállító helyét adja meg. Másik lehetőségként azAssemblyNameattribútum használatával megadhatja a beágyazott feladat-előállító osztály teljes nevét, amely általában a globális szerelvény-gyorsítótárban (GAC) található.
A tevékenység fennmaradó elemei DoNothing üresek, és a beágyazott tevékenységek sorrendjének és szerkezetének szemléltetésére szolgálnak. A cikk későbbi részében egy robusztusabb példát mutatunk be.
Az
ParameterGroupelem nem kötelező. Ha meg van adva, deklarálja a tevékenység paramétereit. A bemeneti és kimeneti paraméterekkel kapcsolatos további információkért lásd a cikk későbbi, bemeneti és kimeneti paramétereit .Az
Taskelem leírja és tartalmazza a tevékenység forráskódját.Az
Referenceelem a kódban használt .NET-szerelvényekre mutató hivatkozásokat adja meg. Ez egyenértékű azzal, ha egy projektre mutató hivatkozást ad hozzá a Visual Studióban. AzIncludeattribútum a hivatkozott szerelvény elérési útját adja meg.Az
Usingelem felsorolja a elérni kívánt névtereket. Ez az elem hasonlít ausingVisual C# irányelvére. AzNamespaceattribútum megadja a belefoglalandó névteret.
Reference és Using az elemek nyelvi agnosztikusak. A beágyazott feladatok a támogatott .NET CodeDom nyelvek bármelyikében írhatók, például Visual Basic vagy Visual C# nyelven.
Megjegyzés:
Az elem által Task tartalmazott elemek a feladat-előállítóra, ebben az esetben a kód-feladat-előállítóra vonatkoznak.
Kódelem
Az elemen belül Task az utolsó gyermekelem az Code elem. Az Code elem tartalmazza vagy megkeresi a feladatba lefordítani kívánt kódot. Az elembe Code helyezett elemek attól függenek, hogyan szeretné megírni a feladatot.
Az Language attribútum azt a nyelvet határozza meg, amelyben a kód meg van írva. Az elfogadható értékek a cs C#, vb a Visual Basic esetében.
Az Type attribútum megadja az elemben Code található kód típusát.
Ha az érték
TypeazClass, akkor azCodeelem egy olyan osztály kódját tartalmazza, amely a ITask felületből származik.Ha az érték
TypeazMethod, akkor a kód a felület metódusánakExecutefelülbírálását ITask határozza meg.Ha az érték
TypeazFragment, akkor a kód határozza meg aExecutemetódus tartalmát, de az aláírást vagy az utasítástreturnnem.
Maga a kód általában egy jelölő és egy <![CDATA[]]> jelölő között jelenik meg. Mivel a kód egy CDATA-szakaszban található, nem kell aggódnia a fenntartott karakterek, például a "<" vagy a ">" elől.
Másik lehetőségként az Source elem attribútumával Code megadhatja a feladat kódját tartalmazó fájl helyét. A forrásfájl kódjának az attribútum által Type megadott típusnak kell lennie. Ha az Source attribútum jelen van, az alapértelmezett érték az TypeClass. Ha Source nincs jelen, az alapértelmezett érték a következő Fragment: .
Megjegyzés:
Ha egy forrásfájlban definiálja a feladatosztályt, az osztály nevének meg kell egyeznie a TaskName megfelelő UsingTask elem attribútumával.
„Helló világ!” alkalmazás
Íme egy robusztusabb beágyazott feladat a következővel RoslynCodeTaskFactory: . A HelloWorld feladat az alapértelmezett hibanaplózó eszközön jeleníti meg a "Hello, world!" szöveget, amely általában a rendszerkonzol vagy a Visual Studio Kimeneti ablaka. A Reference példában szereplő elem csak illusztrációként szerepel.
<Project>
<!-- This simple inline task displays "Hello, world!" -->
<UsingTask
TaskName="HelloWorld"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup />
<Task>
<Reference Include="System.Xml"/>
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
// Display "Hello, world!"
Log.LogError("Hello, world!");
]]>
</Code>
</Task>
</UsingTask>
</Project>
A feladatot egy HelloWorld.targets nevű fájlba menthetiHelloWorld, majd meghívhatja egy projektből az alábbiak szerint.
<Project>
<Import Project="HelloWorld.targets" />
<Target Name="Hello">
<HelloWorld />
</Target>
</Project>
Bemeneti és kimeneti paraméterek
A beágyazott tevékenységparaméterek egy ParameterGroup elem gyermekelemei. Minden paraméter az azt meghatározó elem nevét veszi fel. A paramétert Textaz alábbi kód határozza meg.
<ParameterGroup>
<Text />
</ParameterGroup>
A paraméterek egy vagy több attribútummal rendelkezhetnek:
Requiredalapértelmezés szerint nem kötelező attribútumfalse. Hatrue, akkor a paraméter megadása kötelező, és a feladat meghívása előtt meg kell adni egy értéket.ParameterTypealapértelmezés szerint nem kötelező attribútumSystem.String. Bármilyen teljesen minősített típusra állítható be, amely egy elem vagy egy olyan érték, amely a System.Convert.ChangeType használatával sztringgé alakítható át. (Más szóval minden olyan típus, amely átadható egy külső tevékenységnek, és amelyből át lehet adni.)Outputalapértelmezés szerint nem kötelező attribútumfalse. Hatrue, akkor a paraméternek meg kell adni egy értéket, mielőtt az Execute metódusból tér vissza.
Például
<ParameterGroup>
<Expression Required="true" />
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Tally ParameterType="System.Int32" Output="true" />
</ParameterGroup>
a következő három paramétert határozza meg:
Expressiona System.String típusú kötelező bemeneti paraméter.Filesegy kötelező elemlista bemeneti paramétere.TallyEgy System.Int32 típusú kimeneti paraméter.
Ha az Code elem attribútuma TypeFragment vagy Method, akkor a rendszer minden paraméterhez automatikusan létrehozza a tulajdonságokat. A RoslynCodeTaskFactory-ban, ha az Code elem Type attribútuma Classaz , akkor nem kell megadnia azt ParameterGroup, mivel a forráskódból következtet (ez a különbség a forráskódtól CodeTaskFactory). Ellenkező esetben a tulajdonságokat explicit módon deklarálni kell a tevékenység forráskódjában, és pontosan meg kell egyezniük a paraméterdefiníciókkal.
példa
Az alábbi beágyazott feladat naplóz néhány üzenetet, és visszaad egy sztringet.
<Project>
<UsingTask TaskName="MySample"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildBinPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Parameter1 ParameterType="System.String" Required="true" />
<Parameter2 ParameterType="System.String" />
<Parameter3 ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Log.LogMessage(MessageImportance.High, "Hello from an inline task created by Roslyn!");
Log.LogMessageFromText($"Parameter1: '{Parameter1}'", MessageImportance.High);
Log.LogMessageFromText($"Parameter2: '{Parameter2}'", MessageImportance.High);
Parameter3 = "A value from the Roslyn CodeTaskFactory";
]]>
</Code>
</Task>
</UsingTask>
<Target Name="Demo">
<MySample Parameter1="A value for parameter 1" Parameter2="A value for parameter 2">
<Output TaskParameter="Parameter3" PropertyName="NewProperty" />
</MySample>
<Message Text="NewProperty: '$(NewProperty)'" />
</Target>
</Project>
Ezek a beágyazott feladatok egyesíthetik az elérési utakat, és lekérhetik a fájlnevet.
<Project>
<UsingTask TaskName="PathCombine"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildBinPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Paths ParameterType="System.String[]" Required="true" />
<Combined ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Combined = Path.Combine(Paths);
]]>
</Code>
</Task>
</UsingTask>
<UsingTask TaskName="PathGetFileName"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildBinPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Path ParameterType="System.String" Required="true" />
<FileName ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Code Type="Fragment" Language="cs">
<![CDATA[
FileName = System.IO.Path.GetFileName(Path);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="Demo">
<PathCombine Paths="$(Temp);MyFolder;$([System.Guid]::NewGuid()).txt">
<Output TaskParameter="Combined" PropertyName="MyCombinedPaths" />
</PathCombine>
<Message Text="Combined Paths: '$(MyCombinedPaths)'" />
<PathGetFileName Path="$(MyCombinedPaths)">
<Output TaskParameter="FileName" PropertyName="MyFileName" />
</PathGetFileName>
<Message Text="File name: '$(MyFileName)'" />
</Target>
</Project>
Visszamenőleges kompatibilitás biztosítása
RoslynCodeTaskFactory először elérhetővé vált az MSBuild 15.8-ás verziójában. Tegyük fel, hogy támogatni szeretné a Visual Studio és az MSBuild korábbi verzióit, amikor RoslynCodeTaskFactory nem volt elérhető, de CodeTaskFactory az volt, de ugyanazt a buildszkriptet szeretné használni. Egy olyan szerkezetet használhat Choose , amely a tulajdonságot használja annak $(MSBuildVersion) eldöntésére, hogy a létrehozáskor használja-e a RoslynCodeTaskFactory tulajdonságot, vagy visszaesik-e CodeTaskFactorya következő példához:
<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="RunTask">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<Choose>
<When Condition=" '$(MSBuildVersion.Substring(0,2))' >= 16 Or
('$(MSBuildVersion.Substring(0,2))' == 15 And '$(MSBuildVersion.Substring(3,1))' >= 8)">
<PropertyGroup>
<TaskFactory>RoslynCodeTaskFactory</TaskFactory>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TaskFactory>CodeTaskFactory</TaskFactory>
</PropertyGroup>
</Otherwise>
</Choose>
<UsingTask
TaskName="HelloWorld"
TaskFactory="$(TaskFactory)"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup />
<Task>
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
Log.LogError("Using RoslynCodeTaskFactory");
]]>
</Code>
</Task>
</UsingTask>
<Target Name="RunTask" AfterTargets="Build">
<Message Text="MSBuildVersion: $(MSBuildVersion)"/>
<Message Text="TaskFactory: $(TaskFactory)"/>
<HelloWorld />
</Target>
</Project>