本人将通过Framework与Core框架,使用常规的开发思想和手段,以对开发过的程序和代码进行重构的方式,渐进的在程序和代码中添加开发模式、控件反转(Inversion of Control,缩写为IoC)、依赖注入(Dependency Injection,简称DI)等开发思想,实现这些思想相应技术手段及其相互关系。为了大家能够容易和逐渐深入的理解,我会显式的指出它们之间的重构逻辑。
即使使用常规开发思想和手段.Net Fromework框架也是在当前来说也大多数开发者最现和最多接触的开框架,所以我的第一个程序就从.Net Fromework框架开始。
为了大家更容易阅读本人的工程和代码,先说一下我的代码书写和架构构建习惯:
1、会有一个独立Models层(或者叫Entity层),它的功能单一即实现现实业务数据与数据库相应表数据的映射和现实业务数据流与相应数据库中的表之间的操作,即增、删、改和查,是整个程序的基石,真正的一发及全身。不会把Models层集成到核心层(Core)或数据层(Data)中,一个独立Models层能把关注更新集中到现实业务领域概念怎样能自然,流畅,自洽、逻辑合理的(逻辑合理包含:现实业务流程合理,Models层中的实体之间的映射合理,以及现实业务与Models层中的实体之间映射合理)映射到软件工程当中,一个好的Models层能从基础层面达到上述效果。如果把它集成入其它层,那么就会分散关注从基础层面就没能把领域驱动设计 (DDD)核心问题解决好。Models层是在程序开始时就要构建,但是它是不可能一开始就能达到上述效果,它存在的生命周期存在于程序开始的整个软件的使用过程中,所以它是根据实际业务和时间的变化不断重构优化的过程,不要想着一蹴而就,但是更为重要的是在进行第一次开发时必须把Models层与现实业务流程的逻辑映射在允许的范围内能做多好就做多好,这样才能在重构时才能节省大量的资源。虽然微软对Models和数据库之间提供了数据迁移操作,但是Models极低频率和极少量的更该在实际开发中可以使用数据迁移操作,如果Models改动量稍微大些,最安全、最保险的方法是对程序进行重构。
2、是对于初学者的一点提示,尽量书写详细的注释,即使是错误的注释也比没能注释强。虽然注释要书写详细,但是最多是所注释对象宽度的1.5—2倍之间,如果再多,这时你有两个选择。第一个选择是写一个错误或者大略的注释,它们的同点是短,在程序完成时去补课。第二个选择你应该放下当下的程序,对注释对象进行针对性的补课。不管那个选择一定要针对性的补课。
3、如果程序中有Web层,我会把Controllers和ViewModel移出Web层,把Controllers单独做一层,ViewModel可能被集成在Controllers层中,Web层只负责显示,这不但有利于整个程序的安全性,还利于分工合作,聚集开发者的关注点。
4、在“程序档案”中存放着“日志”和其它与当前程序开发相关的文件,在看源码前先看这些文件,因此“日志”中记录着在开发过程中,本人遇到的问题和解决方案,这对大家还是有一定帮助的。
“2019-12-12_NoIOCFramework(001控制台常规调用,完成Insert、Update、Delete数据操作验证)”整个工程中的项目都是在“类库(.NET Standard)”基础上构建的,而不是.Net Framework框架常用的“类库(.NET Framework)”。之所以使用“类库(.NET Standard)”不使用“类库(.NET Framework)”构建项目是因为“类库(.NET Framework)”中的引用,不能进行分类,所有的引用依赖显的杂乱无章,而“类库(.NET Framework)”中的依赖按照引用的方式不同对引用进行了分类,使用整个引用依赖显得逻辑清晰一目了然。
因为使用“类库(.NET Standard)”构建基于是.Net Framework框架项目,需要对“类库(.NET Standard)”构建的项目作一些更改。
首先新建两基于“类库(.NET Standard)”两个项目:Models、Data,双击项目可以找到目标框架标签<TargetFramework>netstandard2.0</TargetFramework>,而需要把更改为<TargetFramework>net48</TargetFramework>,因为的所构建的程序的目标框架是基于.NET Framework4.8的。
其次建启动项ConsoleApp它也是基于“类库(.NET Standard)”构建的,首先右击它找到属性左击找到输出类型:把它从“类库”更改为“控制台应用程序”,然后进行第一步操作更换标签为:
<PropertyGroup>
<TargetFrameworks>net48</TargetFrameworks>
<AssemblyName>ConsoleApp</AssemblyName>
<OutputType>Exe</OutputType>
</PropertyGroup>
通过“类库(.NET Standard)”构建的启动项在通过NuGut引用EntityFromework时不会自动的添加App.config文件。如果有一定的开发经验可能通过“类库(.NET Framework)”构建项目在把在通过NuGut引用EntityFromework时自动的添加App.config文件,复制到启动项ConsoleApp中,然后自行做一些关于数据库连接的配置。如果没有可以所我的工作中的App.config文件,直接复制自己的工作中进行使用。
通过程序 “2019-12-12_NoIOCFramework(001控制台常规调用,完成Insert、Update、Delete数据操作验证)”的代码,可以发现该程序使用的都是常规的开发思想和技术程序中所有对象间的声明、定义和调用逻辑最简单,相互关系最清晰(即通过New关键字直接调用)。
把“2019-12-12_NoIOCFramework(001控制台常规调用,完成Insert、Update、Delete数据操作验证)”中的 EFContext.cs文件中指定实体的DbSet属性实例重构为动态实体类型的DbSet方法,通过指定的实体类型,通过指定实体类型的DbSet实例,也可以执行查询、增、删、该等操作,详细信息可以通过“2019-12-12_NoIOCFramework(002控制台动态实体DbSet实例调用模式)”查看。
“2019-12-12_NoIOCFramework(002控制台动态实体DbSet实例调用模式)”首先在“Mapping”添加IMappingConfiguration和EntityTypeConfigurationApply类的定义对此文件夹中所有实体映射的定义进行重构,最后重构EFContext.cs文件中的覆盖方法OnModelCreating,详细信息见“2019-12-12_NoIOCFramework(003控制台OnModelCreating通过程序集查找加载所有实体映射实例)”
/// <summary>
/// 【模型创建】
/// <param name="modelBuilder">模型生成器实例。</param>
/// <remarks>
/// 摘要:
/// OnModelCreating方法可以被用来重载与定制规定我们的模型类如何与我们的数据表进行映射的映射规则。
/// </remarks>
/// </summary>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//移除复数表名的契约,即实体类与数据库表名的单复数形式相同
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
// 通过程序集查找继承于指定父类的类型,找到后动态加载所有实体映射配置实体,
//实际上通过程序集查找获取指定类型的实例,而不通过“new”关键字获取指定类型的实例,
//就是依赖注入的一种方式,此方式被称为:叫“依赖查找”(Dependency Lookup)。
IEnumerable<Type> _entityTypeConfigurationEnumerable = Assembly.GetExecutingAssembly().GetTypes().Where(type =>
(type.BaseType?.IsGenericType ?? false)
&& (type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfigurationApply<>)));
//逐一的从实体/聚合配置对象的集合中选出一个实体/聚合配置对象,在数据库中映射并生成相应的表.
foreach (var item in _entityTypeConfigurationEnumerable)
{
IMappingConfiguration _mappingConfiguration = (IMappingConfiguration)Activator.CreateInstance(item);
_mappingConfiguration.ApplyConfiguration(modelBuilder.Configurations);
}
}
到此为已经对NoIOCFramework应用程序使用常规的开发思想和技术,同时为开发模式和依赖注入作了一些准备工作,所实现的工程的源码地址为:
2019-12-12_NoIOCFramework(001控制台常规调用,完成Insert、Update、Delete数据操作验证)-- https://download.csdn.net/download/zhoujian_911/12029270。
2019-12-12_NoIOCFramework(002控制台动态实体DbSet实例调用模式) --https://download.csdn.net/download/zhoujian_911/12031163
2019-12-12_NoIOCFramework(003控制台OnModelCreating通过程序集查找加载所有实体映射实例) --https://download.csdn.net/download/zhoujian_911/12031172