基于DDD的.NET开发框架 - ABP依赖注入
ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。
ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板。
ABP的官方网站:http://www.aspnetboilerplate.com
ABP官方文档:http://www.aspnetboilerplate.com/Pages/Documents
Github上的开源项目:https://github.com/aspnetboilerplate
一、依赖注入概念
控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。
依赖注入是一种软件设计模式的一个或多个依赖项注入(或服务),或通过引用传递,为依赖对象(或客户)和客户端状态的一部分。模式之间建立一个客户的依赖关系的行为,它允许程序设计是松散耦合的,依赖倒置和单一职责原则。它直接对比service locator模式,它允许客户了解他们所使用的系统找到依赖。
依赖注入不是目的,它是一系列工具和手段,最终的目的是帮助我们开发出松散耦合、可维护、可测试的代码和程序。这条原则的做法是大家熟知的面向接口,或者说是面向抽象编程。
理想的软件开发设计是“高内聚,低耦合”,高内聚侧重面向对象编程,低耦合侧重面向接口编程,控制反转、依赖注入、依赖倒置都蕴含着面向接口编程的思想。
控制反转把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的"控制反转"概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
依赖注入是通过反射(reflection)动态的向某个对象提供它所需要的其他对象、
常用依赖注入框架:
Unity:微软patterns&practicest团队开发的IOC依赖注入框架,支持AOP横切关注点。
MEF(Managed Extensibility Framework):是一个用来扩展.NET应用程序的框架,可开发插件系统。
Spring.NET:依赖注入、面向方面编程(AOP)、数据访问抽象,、以及ASP.NET集成。
Autofac:最流行的依赖注入和IOC框架,轻量且高性能,对项目代码几乎无任何侵入性。
PostSharp:实现静态AOP横切关注点,使用简单,功能强大,对目标拦截的方法无需任何改动。
Castle Windsor、StructureMap、Ninject
其实我感觉Autofac挺好用的,一直用的Autofac,不知道到Castle Windsor怎么样。
二、三层和DDD分层依赖关系
1、三层分层依赖如下图:

从引用关系我们就能知道各层的依赖关系:BLL需要依赖DAL,因为BLL中用到了DAL层的实体。UI这一层需要依赖BLL,还需要依赖DAL,因为在UI中也用到了DAL层实体。
如果从换个数据库,DAL需要修改,那DAL的依赖也需要修改。
2、DDD分层依赖关系图

从上图可以知道,表现层和数据访问层都依赖领域模型层,这样的话,如果我们新添加一个UI界面;更换一种数据源的存储和获取方式,只需要修改对应层的代码即可,领域模型层保持了稳定。
减少new引入的依赖及紧耦合最好的方式是使用构造函数注入依赖这种设计模式:即如果我们需要一个依赖的实例,通过构造函数注入。
解耦和最重要的原则就是依赖倒置原则:
高层模块不应该依赖底层模块,他们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
简单理解就是组件应该依赖于接口而不是实现。
三、ABP依赖注入底层实现
ABP依赖注入是通过Castle Windsor依赖注入的框架实现。
1、通过实现IConventionalDependencyRegistrar的实例定义注入的约定,然后通过IocManager来读取这个规则完成依赖注入
代码在Abp项目文件的Dependency文件夹下

1)在PreInitialize方法中给IocManager的IConventionalDependencyRegistrar的list中加入BasicConventionalRegistrar
IocManager.AddConventionalRegistrar(new BasicConventionalRegistrar());
2)IocManager维护了一个叫_conventionalRegistrars的list,其中的元素类型就是IConventionalDependencyRegistrar。接着IocManager的RegisterAssemblyByConvention是在模块的Initialize方法中被调用
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
3)IocManager在RegisterAssemblyByConvention方法中遍历这个list,并根据IConventionalDependencyRegistrar的实例中定义的规则来完成register。
/// <summary>
/// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
/// </summary>
/// <param name="assembly">Assembly to register</param>
public void RegisterAssemblyByConvention(Assembly assembly)
{
RegisterAssemblyByConvention(assembly, new ConventionalRegistrationConfig());
} /// <summary>
/// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
/// </summary>
/// <param name="assembly">Assembly to register</param>
/// <param name="config">Additional configuration</param>
public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)
{
var context = new ConventionalRegistrationContext(assembly, this, config); foreach (var registerer in _conventionalRegistrars)
{
registerer.RegisterAssembly(context);
} if (config.InstallInstallers)
{
IocContainer.Install(FromAssembly.Instance(assembly));
}
}
2、直接使用IocManager的Register方法直接完成注入
AbpModule有个受保护的IocManager的成员,所以AbpModule的派生类都可以使用这个IocManager完成注册。
public class AbpWebModule : AbpModule
{
/// <inheritdoc/>
public override void PreInitialize()
{
if (HttpContext.Current != null)
{
XmlLocalizationSource.RootDirectoryOfApplication = HttpContext.Current.Server.MapPath("~");
}
//IocManager直接注入
IocManager.Register<IAbpWebModuleConfiguration, AbpWebModuleConfiguration>(); Configuration.Localization.Sources.Add(
new DictionaryBasedLocalizationSource(
AbpWebLocalizedMessages.SourceName,
new XmlEmbeddedFileLocalizationDictionaryProvider(
Assembly.GetExecutingAssembly(), "Abp.Web.Localization.AbpWebXmlSource"
)));
} /// <inheritdoc/>
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
基于DDD的.NET开发框架 - ABP依赖注入的更多相关文章
- 线上分享-- 基于DDD的.NET开发框架-ABP介绍
前言 为了能够帮助.Net开发者开拓视野,更好的把最新的技术应用到工作中,我在3月底受邀到如鹏网.net训练营直播间为各位学弟学妹们进行ABP框架的直播分享.同时为了让更多的.NET开发者了解ABP框 ...
- 基于DDD的.NET开发框架 - ABP领域服务
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架 - ABP初探
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架 - ABP工作单元(Unit of Work)
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架 - ABP仓储实现
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架 - ABP日志Logger集成
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架 - ABP启动配置
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架 - ABP模块设计
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架 - ABP缓存Caching实现
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
随机推荐
- mapreduce流程中的几个关键点
MapReduce中数据流动 (1)最简单的过程: map - reduce (2)定制了partitioner以将map的结果送往指定reducer的过程: map - partiti ...
- apache 虚拟主机详细配置:http.conf配置详解
apache 虚拟主机详细配置:http.conf配置详解 Apache的配置文件http.conf参数含义详解 Apache的配置由httpd.conf文件配置,因此下面的配置指令都是在httpd. ...
- Consul 启动命令
服务端: nohup consul agent -server -bootstrap-expect 1 -config-dir /etc/consul.d/ -data-dir /var/opt/co ...
- SQL Server:字符串函数
以下所有例子均Studnet表为例: 1. len():计算字符串长度 len()用来计算字符串的长度,每个中文汉字或英文字母都为一个长度 select sname, len(sname) from ...
- 今天说一下where 中 exists 和 in 里面的一些区别
in 和 exists 已经成为我们日常查询时候的常客了.很多时候他们2个都是可以互通实现的,但是,无论兄弟怎么亲,还是会有那么一些差别的. 先搞个测试表 )) ),Col2 )) INSERT IN ...
- 为IIS站点添加限制IP
/// <summary> /// 添加站点限制IP /// </summary> /// <param name="sitename">站点名 ...
- iOS 读取相册二维码,兼容ios7(使用CIDetector 和 ZXingObjC)
ios从相册读取二维码,在ios8以上,苹果提供了自带的识别图片二维码的功能,这种方式效率最好,也是最推荐的,但是如果你的系统需要向下兼容ios7,就必须用其他方式. 这里我选择的是 ZXingObj ...
- iOS UIScrollView 无法滚动 没有弹簧效果解决方案
一般情况下,检查如下: 1.没有设置contentSize或者contentSize的尺寸小于等于该scrollView的尺寸 2.scrollView.enable = NO;(仅仅是让scroll ...
- Windows下常用软件工具的命令
Linux上主要操作是命令,懂一点linux知识的都知道,其实windows下边很多工具也是可以用命令来操作打开的,这样会提高效率,节省很多的时间.下边就记录一下常用的命令. 一.常用命令 1.远程桌 ...
- 理解 QEMU/KVM 和 Ceph(1):QEMU-KVM 和 Ceph RBD 的 缓存机制总结
本系列文章会总结 QEMU/KVM 和 Ceph 之间的整合: (1)QEMU-KVM 和 Ceph RBD 的 缓存机制总结 (2)QEMU 的 RBD 块驱动(block driver) (3)存 ...