关于如何将模块名添加到程序集的ModuleName说简单吧也简单,说不简单吧也不简单。

  简单的原因是代码只有几行,不简单的原因是这些都不是c#,都是MSbuild的代码。这可真难为我了,所以这个地方我卡了两个星期。

  首先我们来看下解决方案的目录:

  都知道这些文件夹都是解决方案文件夹,但是build解决方案文件夹里放的是什么,居然不是项目?不是项目如何调用呢,这可触及我的知识盲点。经过多方查阅资料和博问上提问,我重于搞清楚了。

  首先,这两个.yml文件删了也无所谓,我第一次见到yml文件还是在docker的配置上,也就是一个跟我们常用的json一样的配置文件(用缩进代替json里面那堆括号,有人觉得这样比较方便)。开始我还以为是通过其它程序靠yml配置文件注入模块,被误导了好久,这两个配置文件就是持续集成的配置文件(没进过大厂不懂这些被浪费好久),也就是项目发布到github会自动帮你build等等。

  其次,就是剩下的文件是靠Directory.Build.props和Directory.Build.targets调用到项目里的。这就是我的第二个知识盲点了。我们打开文件夹(直接打开资源管理器的,不是visual studio的),可以发现src源码文件夹下的OrchardCore、OrchardCore.Modules和OrchardCore.Themes三个文件夹都有Directory.Build.props和Directory.Build.targets这两个文件。这意味着还有文件不在项目里?这又怎么用呢?我真是快崩溃了!经过查找资料,重要明白:在MSBuild15以后新增一个功能就是让开发者可以自己定义项目信息放在一个文件,这个文件会在Microsoft.Common.props和Microsoft.Common.target引用,而且会在csproj项目文件所在的文件夹开始寻找,只要找到存在Directory.Build.props和Directory.Build.target文件就会自动导入里面的内容。也就是从项目的csproj当前项目开始自动向上寻找Directory.Build.props和Directory.Build.target,直到解决方法根目录,只要找到立即停止。这就是意味着每个项目编译的时候会把这些文件给包括进来。

  好了,明白了这些后,开始按顺序了解模块的加载过程。

  我是从启动项目OrchardCore.Cms.Web开始看,它项目引用了OrchardCore.Application.Cms.Core.Targets,而这个项目又引用了OrchardCore.Application.Targets,这下Targets项目都在OrchardCore文件夹下,也就是编译的时候会包含上面说的Directory.Build.props和Directory.Build.targets文件。

  OrchardCore.Application.Targets里面只有一个OrchardCore.Application.Targets.targets文件,打开如下:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <!--
This file is packaged with "OrchardCore.Application.Targets.nupkg" in "./build" such that any
Application that references it will embed in its assembly a list of the referenced modules.
--> <Target Name="ResolveModuleProjectReferences" AfterTargets="AfterResolveReferences">
<MSBuild
Targets="GetModuleProjectName"
BuildInParallel="$(BuildInParallel)"
Projects="@(_MSBuildProjectReferenceExistent)"
Condition="'@(_MSBuildProjectReferenceExistent)' != ''"
SkipNonexistentTargets="true"
ContinueOnError="true"> <Output ItemName="ModuleProjectNames" TaskParameter="TargetOutputs" />
</MSBuild> <ItemGroup>
<ModuleNames Include="@(ModulePackageNames);@(ModuleProjectNames)" />
</ItemGroup> <ItemGroup>
<AssemblyAttribute Include="OrchardCore.Modules.Manifest.ModuleNameAttribute" Condition="'@(ModuleNames)' != ''">
<_Parameter1>%(ModuleNames.Identity)</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Target> <Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
<PropertyGroup>
<NoWarn>$(NoWarn);0436</NoWarn>
</PropertyGroup>
</Target> </Project>

  看到AssemblyAttribute元素了吧,没错,这就是程序集的属性啊,在看看它里面有啥?OrchardCore.Modules.Manifest.ModuleNameAttribute,没错,这个就是上篇反射找到的ModuleName,那么怎么来的呢,有个Condition="'@(ModuleNames)' != ''",明显这个条件就是ModuleNames元素不为空,然后获取ModuleNames元素的Identity。那么我们顺着往上看就可以看到上个ItemGroup元素里面就包含ModuleNames,但是没有Identity属性啊,只能查阅资料了,谁叫我MSbuild两眼一抹黑呢,根据msdn介绍明白Identity就是Include属性中指定的项,大家也可以看看msdn。那么我们接着看INclude,@(ModulePackageNames);@(ModuleProjectNames),分号间隔符,间隔而已,继续看看第二个ModuleProjectNames,上面的MSBuid的Oupt就是了,而任务呢,就是MSBuild的GetModuleProjectName。这个任务在哪呢,感觉很无厘头是不是,不对,前面不是介绍了Directory.Build.props和Directory.Build.targets吗,没错,往里面找,打开Directory.Build.targets看看

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Import Project="..\OrchardCore.Build\OrchardCore.Commons.targets" />
<Import Project="..\OrchardCore\OrchardCore.Module.Targets\OrchardCore.Module.Targets.targets" /> <PropertyGroup>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup> </Project>

  看到里面包含了的OrchardCore.Module.Targets.targets文件没有,打开接着看(这个有点长直接看最后部分):

 

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  ...

  <Target Name="GetModuleProjectName" Returns="@(ModuleProjectName)">
<ItemGroup>
<ModuleProjectName Include="$(AssemblyName)" />
</ItemGroup>
</Target> </Project>

  看到Name为GetModuleProjectName的Target任务了吧,请注意这个文件的位置,在..\OrchardCore\OrchardCore.Module.Targets\OrchardCore.Module.Targets.targets,没错就在OrchardCore.Module.Targets项目里,而所有模块都是以用这个项目,也就是说所有应用这个项目的项目名都会加到程序集的ModuleName上!

最新文章

  1. 分享在winform下实现模块化插件编程-优化版
  2. Tomcat:利用Apache配置反向代理、负载均衡
  3. django 模型
  4. cloudsim安装,配置(到eclipse)
  5. Win7-其中的文件夹或文件已在另一个程序中打开
  6. [Sciter系列] MFC下的Sciter&ndash;3.Sciter脚本与底层交互
  7. linux 硬盘相关命令学习
  8. 教程-Delphi7 自带控件安装对应表
  9. 【HDOJ】1315 Basic
  10. 使用opencv传中文文件崩溃
  11. Eclipse设置Android Logcat输出字体大小
  12. Eclipse 改动凝视的 date time 日期时间格式,即${date}变量格式
  13. 5、Web应用程序中的安全向量 -- Open Redirect Attack(开放重定向)
  14. stl_组件
  15. Ubuntu 虚拟机支持与windows机器复制粘贴
  16. 解决:HTTP 错误 404.0 - Not Found.您要找的资源已被删除、已更名或暂时不可用。(记录帖)
  17. java基本类型(数值范围):浮点的底层表示定义,float计算快一些
  18. JS中if判断 非空即为真 非0即为真
  19. Finance财务软件(自定义报表专题)
  20. Linux下批量Kill多个进程

热门文章

  1. 力扣:二叉树着色游戏(DFS详解)
  2. cb35a_c++_STL_算法_for_each
  3. 微信小程序踩坑之前端问题处理篇
  4. MonoBehaviour.StartCoroutine开启协同程序
  5. 【转】Windows下PATH等环境变量详解
  6. VMware Workstation 15密钥
  7. 8.eclipse 安装 lombook插件
  8. RabbitMQ:一、入门
  9. 【题解】[BalticOI 2014]friends
  10. jmeter使用小结(一)