一些诗歌:
就我而言-我需要专门为unit test 项目构建插件dlls。如果您以“正常方式”为每个插件创建单独的项目,那么您最终将拥有更多与核心程序集相比,单元测试相关的项目。所以我认为在某些情况下,值得在同一个项目中进行多重构建。话虽如此 - 我想提供已接受答案的改进版本。
新方法改进:
- 支持新的
SDK 项目(用于 .net Core)
- 支持构建引用解决方案中其他项目的程序集!
新建一个空库项目,确保结构如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
</Project>
提示:您可以创建 .Net core 项目并将目标更改为 net472,例如。
如果需要,添加一个插件和一些参考,然后,根据以下文档,添加:
https://docs.microsoft.com/en-us/dotnet/core/tools/csproj
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
这将使手动包含用于构建的文件成为可能。否则构建将默认包含所有文件。
然后显式添加要编译的项:
<ItemGroup>
<Compile Include="TestApp1.cs">
<Plugin>true</Plugin>
</Compile>
</ItemGroup>
然后,如以下来源中所述 - 您可以将所有引用聚合到一个字符串中:How to get paths to all referenced DLLs in MSBuild?
<Target Name="GatherReferences" DependsOnTargets="ResolveReferences">
<ItemGroup>
<MyReferencedAssemblies Include="@(ReferencePath)" />
</ItemGroup>
</Target>
测试:
<Target Name="TestMessage" AfterTargets="Build" >
<Message Text="Referenced assemblies: @(ReferencePath)" Importance="high"/>
</Target>
然后你必须附加一个在 PostBuild 上触发的构建目标:
<Target Name="BuildPlugins" AfterTargets="PostBuildEvent">
<CSC Condition="%(Compile.Plugin) == 'true'"
Sources="%(Compile.FullPath)"
TargetType="library"
References="@(ReferencePath)"
OutputAssembly="$(OutputPath)%(Compile.FileName).dll"
EmitDebugInformation="true" />
</Target>
您会注意到这里的区别是 References 属性,它基本上将值转换为 CSC 编译器的适当 -reference 参数:https://docs.microsoft.com/en-us/visualstudio/msbuild/csc-task?view=vs-2019
奖励:您可以将此逻辑合并到您的项目中,即使无需明确定义 Plugin 属性..
这里根据这个话题:MsBuild Condition Evaluate Property Contains
可以在构建元数据上使用正则表达式:https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-well-known-item-metadata?view=vs-2019
所以基本上,这样的事情是允许的:
Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Compile.Filename)', 'Plugin'))"
您可以这样做,如果类文件名包含特定关键字,那么您可以触发对此类文件的单独编译。或者如果文件位于特定位置文件夹!在上面的示例中,如果文件中包含单词“Plugin”,那么它将被 CSC 任务拾取。我建议检查元数据页面以查看所有选项。
奖励:如果您像我一样喜欢能够进入代码并能够输出到Debug 输出窗口,您还可以定义:
DefineConstants="DEBUG;TRACE"
DebugType="full"
我的最新配置如下:
<Target Name="BuildPlugins" AfterTargets="PostBuildEvent">
<CSC
Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Compile.FullPath)', '.*\\AppUnitTests\\Plugins\\.*.cs'))"
Sources="%(Compile.FullPath)"
TargetType="library"
References="@(ReferencePath)"
OutputAssembly="$(OutputPath)Plugins\%(Compile.FileName).dll"
EmitDebugInformation="true"
DefineConstants="DEBUG;TRACE"
DebugType="full" />
</Target>
希望它对某人有用;)
附言感谢原作者提供了一个我可以改进的例子。