关于如何将模块名添加到程序集的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上!

(四)学习了解OrchardCore笔记——将模块的名字添加到程序集的ModuleName的更多相关文章

  1. (五)学习了解OrchardCore笔记——灵魂中间件ModularTenantContainerMiddleware的第一行②模块的功能部分

    在(三)的时候已经说到模块集合用ForEachAsync的扩展方法分配多个任务,把每个modules的ManifestInfo分析出来的功能加入ConcurrentDictionary.我们先看看这个 ...

  2. (三)学习了解OrchardCore笔记——灵魂中间件ModularTenantContainerMiddleware的第一行①的模块部分

    了解到了OrchardCore主要由两个中间件(ModularTenantContainerMiddleware和ModularTenantRouterMiddleware)构成,下面开始了解Modu ...

  3. (二)学习了解OrchardCore笔记——开篇:OrchardCore的中间件

    现在开始看Starpup的中间件.这是一个扩展方法app.UseOrchardCore() public void Configure(IApplicationBuilder app, IHostEn ...

  4. (一)学习了解OrchardCore笔记——开篇:基于asp.net core的OrchardCore

    想深入了解OrchadCore源码许久了,但是读源码的时候遇到很多问题而网上的参考资料太少了(几乎都是OrchadCms不带OrchardCore的),现在解决得差不多了,做下笔记方便自己查看,有错误 ...

  5. python学习笔记013——模块

    1 模块module 1.1 模块是什么 模块是包含一系列的变量,函数,类等程序组 模块通常是一个文件,以.py结尾 1.2 模块的作用 1. 让一些相关的函数,变量,类等有逻辑的组织在一起,使逻辑更 ...

  6. hadoop2.5.2学习及实践笔记(四)—— namenode启动过程源码概览

    对namenode启动时的相关操作及相关类有一个大体了解,后续深入研究时,再对本文进行补充 >实现类 HDFS启动脚本为$HADOOP_HOME/sbin/start-dfs.sh,查看star ...

  7. Python学习的个人笔记(基础语法)

    Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...

  8. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  9. Elasticsearch7.X 入门学习第一课笔记----基本概念

    原文:Elasticsearch7.X 入门学习第一课笔记----基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https: ...

随机推荐

  1. CDN百科第四讲 | 如何优雅地在云上“摆摊”——做直播带货,你不得不关注的技术

    最近,国家政策开始鼓励“地摊经济”,一时间各家企业平台纷纷推出地摊扶持政策,地摊概念股顺势大涨,地摊生态及配套商品也开始走俏,甚至在网络上也涌现出各种“新摊主速成攻略”,万亿的烟火经济俨然已经走上风口 ...

  2. TCP 重置攻击的工作原理

    原文链接:https://fuckcloudnative.io/posts/deploy-k3s-cross-public-cloud/ TCP 重置攻击 是使用一个单一的数据包来执行的,只有几个字节 ...

  3. 利用ssm框架做一个客户管理系统

    1. 需求分析 (1)初始化查询条件下拉列表 (2)展示客户列表,并且可以根据查询条件过滤查询结果,并且实现分页处理. (3)修改客户信息: 1)点击客户列表中的“修改”按钮弹出客户信息修改对话框,并 ...

  4. selenium自动化操作

    在前面爬虫的相关介绍中,我们介绍了如何抓取静态页面信息.但是,在实际的网页浏览过程中,我们可能会经常碰到各种需要进行交互的操作,典型的如输入信息.点击按钮之类. 对于这种场景,之前的静态页面操作方式已 ...

  5. Vmaware克隆虚拟机后无法上网

    问题: 使用快照克隆了一台虚拟机 打开后发现无法上网,ifconfig查看状态 解决办法: 1.点击右下角的网络设置,点击设置,查看mac地址与文件/etc/udev/rules.d/70-persi ...

  6. idea安装docker插件

    Preferences->Plugins 根据上图安装docker插件,安装完成后可使用idea来管理docker项目了.docker运行项目请参加"Docker开发环境搭建" ...

  7. jquery-form详解

    jQuery-Form 概观 jQuery表单插件允许您轻松而不显眼地升级HTML表单以使用AJAX.主要方法ajaxForm和ajaxSubmit从表单元素收集信息以确定如何管理提交过程.这两种方法 ...

  8. 7000 字说清楚 HashMap,面试点都在里面了

    我是风筝,公众号「古时的风筝」,一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...

  9. 传统声学模型之HMM和GMM

    声学模型是指给定声学符号(音素)的情况下对音频特征建立的模型. 数学表达 用 \(X\) 表示音频特征向量 (观察向量),用 \(S\) 表示音素 (隐藏/内部状态),声学模型表示为 \(P(X|S) ...

  10. SpringCloud项目配置加载顺序

    bootstrap.yml:位于jar包外的优先级最高 application.yml: 配置中心的文件 > JVM参数配置> 本地active指定文件 > 本地default文件, ...