幸福框架:如何阅读幸福框架的代码
HappyFramework是一个支持DDD、CQRS、OSGI、EPC、EventDriven、MetadataDrivenProgramm理念的开源框架,而且她是可以实战的。
不要被上边的话给欺骗了,当然了,其实也没有欺骗大家,只是HappyFramework的CQRS、OSGI、EPC、EventDrivent、MetadataDrivenProgramming都是实现的很简单,全是限制在AppDomain内和仅支持单线程。这并不代表不可以跨越AppDomain甚至无理进程,或者支持多线程,只是如果想做到这一步,已经有很多的框架提供此类功能了,如:NServiceBus之类的框架。而HappyFramework可以和他们结合起来一起使用的。
下面对整个框架的组织方式和理念做一个简单的介绍,有朋友想阅读这个框架也可以按照这个顺序。
项目组织方式(忽略对单元测试项目的介绍)
- Happy,此项目包含了所有基类和接口,不对其它项目有任何引用。
- Happy.Data.EntityFramework,使用EntityFramework实现了仓储和工作单元,后面计划提供Happy.Data.HHibernate,CQRS的Command部分的数据库访问代码会使用此空间。
- Happy.Data.FluentData,使用FluentData实现了查询服务和查询数据源,CQRS的Query部分的数据访问代码会使用此空间。
- Happy.EnterpriseLibrary,使用了EnterpriseLibrary实现了日志功能和异常管理功能。
- Happy.Ioc.Unity,使用Unity管理AppDomain内的服务,实现了IBundleContainerPlug,当Bundle启动的时候根据约定注册类型到Unity中,当Bundle停止的时候根据约定取消类型的注册;提供了IUnityRegister接口,当Bundle启动时会自动调用所在Assembly中实现了此接口的类型,开发人员可以实现这个接口来自定义注册。
- Happy.Web.Mvc,重写了ControllerFactory,以支持识别动态加载的Bundle中的Controller,而且当Bundle停止时,要取消对相应Conroller的识别。
Happy.DesignByContract介绍
“Happy.DesignByContract”命名空间下的代码基本全是拷贝自“sharparchitecture”,对于契约式开发,我还没有深入了解,正在学习中。
“sharparchitecture”下载地址:http://sharparchitecture.net/。
Happy.Specifications介绍
“Happy.Specifications”命名空间下的代码基本全是拷贝自“microsoftnlayerapp”,其理念基础是领域驱动设计的“规约模式”,我之所以没有将其组织到“Happy.Domain”命名空间的原因是“Happy.Queries”命名空间也需要“规约模式”。
关于规约模式我是这么理解的,规约分查询规约、创建规约、验证规约,其中查询规约又分数据库查询规约和内存查询规约,“Happy.Specifications”命名空间下实现的是“数据库查询规约”,也叫“查询对象”,其它规约类型我会提供独自的继承体系。
“microsoftnlayerapp”下载地址:http://microsoftnlayerapp.codeplex.com/。
Happy.Logging介绍
“Happy.Logging”的开发受到了“log4net”的影响,原本我想用其提供的NuGet包进行开发,后来之所以
决定引入隔离接口,有如下原因:
-
- 我不希望绑定到特定的日志实现。
- 不希望依赖太多外部程序集。
核心类型说明:
-
- ILoger :完全拷贝自“log4net”。
- ILogerFactory :简单工厂模式。
- LogHelper :门面模式。
- EmptyLoger :NullObject模式。
- EmptyLogerFactory:NullObject模式。
“log4net”下载地址:http://logging.apache.org/log4net/。
Happy.ExceptionHandling介绍
“Happy.ExceptionHandling”的开发受到了“ENTERPRISE LIBRARY”的影响,原本我想用其提供的NuGet包进行开发,后来之所以决定引入隔离接口,有如下原因:
-
- 我不希望绑定到特定的日志实现。
- 不希望依赖太多外部程序集。
"ENTERPRISE LIBRARY"下载地址:https://entlib.codeplex.com/。
Happy.ExtensionMethods介绍
“Happy.ExtensionMethods”命名空间下的代码基本全是拷贝自“Craig's Utility Library”,原本我想用其提供的NuGet包进行开发,后来之所以决定进行拷贝式复用,有如下原因:
-
- 我只需要简单的功能。
- 拷贝的过程也是我学习的过程。
- 不希望依赖太多外部程序集。
“Craig's Utility Library”下载地址:http://cul.codeplex.com/、http://www.gutgames.com/。
Happy.Messaging介绍
“Happy.Messaging”的开发受到了“sharparchitecture”的影响,其理念基础是“命令模式”、“发布订阅模式”、“管道过滤器模式”,我准备使用三种消息机制,DomainEvent、ApplicationEvent、Command,他们三者共享一个一个基类框架(Happy.Messaging)。
核心类型说明:
-
- IMessage :消息实体,多数场景只包含数据。
- IMessageHandler :消息处理器,一个消息对应多个消息处理器。
- MessageScene :消息场景,一个消息可以使用在多个场景中,每个消息处理器只能用在一个场景中。
- IMessageFilter :消息拦截器,一个消息被发送到消息处理器之前,会经过多个消息拦截器。
- IMessagePipeLine :消息管道,代表了一个消息从发送、经过过滤器、再到处理器处理的整个过程。
- MessageFilterAttribute :消息拦截器标签,将某个消息拦截器应用到指定的消息上。
- MessageBus :消息总线,代表一个AppDomain内消息总线。
“sharparchitecture”下载地址:http://sharparchitecture.net/。
Happy.OSGI介绍
“Happy.OSGI”命名空间实现了简单的OSGI思想,OSGI的核心理念是管理Bundle的生命周期(安装、启动、停止)。
核心类型说明:
-
- Bundle :Bundle实例,你可以启动它、停止它,但是不能卸载它。
- BundleAttribute :Bundle标注,程序集被标注后,就会被识别为一个Bundle。
- BundleContainer :Bundle容器,一个AppDomain只有一个BundleContainer,它来管理所有Bundle实例。
- BundleContext :Bundle上下文,代表了Bundle当前的上下文信息,在IBundleListener被调用时,会传递给IBundleListener的Start和Stop方法。
- BundleData :Bundle元数据,代表了一个Bundle的原信息,目前只有Assembly,后面会扩充更多信息。
- IAssemblyLoader :程序集加载器,BundleContainer可以使用多个程序集加载器加载Bundle。
- IBundleContainerPlug :BundleContainer插件,Bundle的Start和Stop方法执行时,会自动调用的所有IBundleContainerPlug,如:Ioc自动注册插件可以自动注册Ioc容器。
- IBundleListener :Bundle监听者,Bundle的Start和Stop方法执行时,会自动调用Bundle所在Assembly的所有IBundleListener。
Happy.Domain介绍
“Happy.Domain”命名空间下的代码借鉴了“microsoftnlayerapp”,其理念基础是领域驱动设计。
“microsoftnlayerapp”下载地址:http://microsoftnlayerapp.codeplex.com/。
Happy.Queries介绍
“Happy.Queries”命名空间封装了UI层常用的查询API,此命名空间体现了CQRS的Q。关于如何处理系统的查询,我是这么
理解的,代码中不要出现复杂的查询,复杂的查询应当放到数据库中,通过存储过程或视图实现,程序中只能出现简单的Where查询。
元数据驱动开发也会在该层体现,通过为ViewModel设置应有的元数据,可以在编译时或运行时自动生成UI。
Happy.Commands介绍
“Happy.Commands”继承“Happy.Messaging”的所有实现,为Create、Deleting、Updating提供几个常见的命令基类。CommandBus主要用在控制器层向应用层传递消息,即纵向传递。
Happy.Application介绍
“Happy.Application”继承“Happy.Messaging”的所有实现,为Create、Deleting、Updating提供几个常见的命令处理器基类。ApplicationBus主要用在业务模块和业务模块之间的消息传递,即横向传递。
备注
还是有些乱,找个时间再重新整理一下。