My goal is to run tasks in .NET Core (akin to rake
in Rails land), so I can execute code outside the normal control flow of the application's lifecycle. I have seen there are projects like albacore that supposedly accomplish this, but I'm trying to do it "the .NET way", rather than bringing in a separate ruby dependency to accomplish this.
After following this article on Task Writing for msbuild
, I have managed to create a simple Task
that implements the ITask
interface as suggested in the article:
EcommerceSite/Tasks/ScrapeAll.cs
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Tasks
{
public class ScrapeAll : Task
{
public override bool Execute()
{
return true;
}
}
}
My .csproj
file uses the UsingTask
element to register my task code, and I have a Target
that invokes the task:
EcommerceSite/EcommerceSite.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" />
<PackageReference Include="Microsoft.Build.Framework" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.3.409" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Views\ItemPage\" />
<Folder Include="Tasks\" />
</ItemGroup>
<UsingTask TaskName="Tasks.ScrapeAll" AssemblyFile="bin/Debug/netcoreapp2.0/EcommerceSite.dll" />
<Target Name="ScrapeAll">
<Tasks.ScrapeAll />
</Target>
</Project>
So now, on my command line, I am able to invoke: dotnet msbuild /t:ScrapeAll
and yet, I get this error:
error MSB4062: The "Tasks.ScrapeAll" task could not be loaded from the assembly
[redacted]/EcommerceSite/bin/Debug/netcoreapp2.0/EcommerceSite.dll.
Could not load file or assembly 'Microsoft.AspNetCore.Mvc.ViewFeatures,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
The system cannot find the file specified.
[redacted]/EcommerceSite/EcommerceSite.csproj(33,5): error MSB4062:
Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available,
and that the task contains a public class that implements Microsoft.Build.Framework.ITask
So my questions are:
Task
trying to load Microsoft.AspNetCore.Mvc.ViewFeatures
, which according to the NuGet docs, contains:
view rendering features such as view engines, views, view components, and HTML helpers
of which my Task
does nothing of the sort?
I got this working tonight. You can see my solution here.
In essence, I hit 2 problems:
<UsingTask TaskName="PublishValidationTask" AssemblyFile="C:\git\CustomBuildTargets\PublishPipelineTesting\bin\debug\netcoreapp2.0\PublishPipelineTesting.dll" />
C:\git\CustomBuildTargets\PublishPipelineTesting>dotnet msbuild PublishPipelineTesting.csproj Microsoft (R) Build Engine version 15.7.179.6572 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. PublishPipelineTesting -> C:\git\CustomBuildTargets\PublishPipelineTesting\bin\Debug\netcoreapp2.0\PublishPipelineTesting.dll This is a test Hello World
AssemblyFile="bin\debug\netcoreapp2.0\PublishPipelineTesting.dll" />
Once I got that working, and the custom task running, return true/false would allow the build to pass or fail, which is exactly what I wanted. When returning "false", I would now get:
C:\git\CustomBuildTargets\PublishPipelineTesting>dotnet run PublishPipelineTesting.csproj
The build failed. Please fix the build errors and run again.
When return true out of the task, the build would pass and the project would run:
C:\git\CustomBuildTargets\PublishPipelineTesting>dotnet run PublishPipelineTesting.csproj
Hello World!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With