(四)学习了解OrchardCore笔记——将模块的名字添加到程序集的ModuleName
关于如何将模块名添加到程序集的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的更多相关文章
- (五)学习了解OrchardCore笔记——灵魂中间件ModularTenantContainerMiddleware的第一行②模块的功能部分
在(三)的时候已经说到模块集合用ForEachAsync的扩展方法分配多个任务,把每个modules的ManifestInfo分析出来的功能加入ConcurrentDictionary.我们先看看这个 ...
- (三)学习了解OrchardCore笔记——灵魂中间件ModularTenantContainerMiddleware的第一行①的模块部分
了解到了OrchardCore主要由两个中间件(ModularTenantContainerMiddleware和ModularTenantRouterMiddleware)构成,下面开始了解Modu ...
- (二)学习了解OrchardCore笔记——开篇:OrchardCore的中间件
现在开始看Starpup的中间件.这是一个扩展方法app.UseOrchardCore() public void Configure(IApplicationBuilder app, IHostEn ...
- (一)学习了解OrchardCore笔记——开篇:基于asp.net core的OrchardCore
想深入了解OrchadCore源码许久了,但是读源码的时候遇到很多问题而网上的参考资料太少了(几乎都是OrchadCms不带OrchardCore的),现在解决得差不多了,做下笔记方便自己查看,有错误 ...
- python学习笔记013——模块
1 模块module 1.1 模块是什么 模块是包含一系列的变量,函数,类等程序组 模块通常是一个文件,以.py结尾 1.2 模块的作用 1. 让一些相关的函数,变量,类等有逻辑的组织在一起,使逻辑更 ...
- hadoop2.5.2学习及实践笔记(四)—— namenode启动过程源码概览
对namenode启动时的相关操作及相关类有一个大体了解,后续深入研究时,再对本文进行补充 >实现类 HDFS启动脚本为$HADOOP_HOME/sbin/start-dfs.sh,查看star ...
- Python学习的个人笔记(基础语法)
Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...
- Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究
Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: 反射的概念是由Smith在1982年首次提出的 ...
- Elasticsearch7.X 入门学习第一课笔记----基本概念
原文:Elasticsearch7.X 入门学习第一课笔记----基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https: ...
随机推荐
- MSSQL2008下备份好的*.bak--->>>恢复到--->>>MSSQL2014(解决办法)
MSSQL2008下备份好的*.bak--->>>恢复到--->>>MSSQL2014(解决办法) 在进行CTE训练时(同时也要理解下窗口函数的应用),发现不能继续 ...
- 面试必问:分布式锁实现之zk(Zookeeper)
点赞再看,养成习惯,微信搜索[三太子敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的 ...
- Hadoop + Hive + HBase + Kylin伪分布式安装
问题导读 1. Centos7如何安装配置? 2. linux网络配置如何进行? 3. linux环境下java 如何安装? 4. linux环境下SSH免密码登录如何配置? 5. linux环境下H ...
- WEditor(元素定位工具)安装和定位界面元素
1. 安装adb(安装方法——百度网盘(无邪)) 2. 安装python-uiautomator2 pip install --pre -U uiautomator2 3. 手机设备安装atx-ag ...
- 2、Redis如何配置成一个windows服务并且设置一键安装卸载与启停
每天启动redis虽然只是一个命令行的事情,但是还是比较烦,所以…… 参考文档:Windows Service Documentation.docx 默认前提:Redis已安装并配置完成(不知道如何配 ...
- C++ 进阶 模板和STL
C++提高编程 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 模板的特点: 模板不可以直接使用,它只 ...
- 设计模式系列之组合模式(Composite Pattern)——树形结构的处理
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- docker配置国内镜像地址,解决无法pull镜像问题docker: Error response from daemon
问题: 执行命令 $ docker run -it --rm -p 8888:8080 tomcat:8.5.32 报错 Unable to find image 'tomcat:8.5.32' lo ...
- Redis设置并查看最大连接数
在 Redis2.4 中,最大连接数是被直接硬编码在代码里面的,而在2.6版本中这个值变成可配置的. maxclients 的默认值是 10000,你也可以在 redis.conf 中对这个值进行修改 ...
- c++教程网经典的c语音学习视频教程