基于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
一、如何把带zero模块的abp运行起来
今天我们在官网生成模版的页面:http://www.aspnetboilerplate.com/Templates 生成一个带zero模块的abp解决方案。

生成完了后打开,解决目录结构如下:

执行Code First Migrations 两个命令:
Add-Migration “AbpZero_Installed”
Update-Databse
但总是执行失败如下图:

我们注意到 Data Scource 竟然是 .\\SQLEXPRESS 而不是我们想要的 localDB 。 如果我们安装了 SQL Express,那么 database 将会安装在 local SQL Express instance,否则 Code First 才将尝试使用 localDB。
最好的解决办法就是默认信任连接字符串换成标准安全连接,问题解决
信任连接
<add name="FirstCodeFirstApp" connectionString="Server=.;Database=CodeFirstApp;Integrated Security=SSPI" providerName="System.Data.SqlClient"/>
标准安全连接
<connectionStrings>
<add name="Default" connectionString="Data Source =.;Initial Catalog = FirstAbpZero;User Id = sa;Password = 123;" providerName="System.Data.SqlClient" />
</connectionStrings>
运行起来用默认的用户名:admin 密码:123qwe 登录,也可以自己注册一个,但是默认租户要填写default;登录页面
注册页面

admin登录后添加用户页面

虽然运行起来了好像和今天要说的配置关系不大,下面进入正题。
二、ABP启动配置
配置ABP
public class SimpleTaskSystemModule : AbpModule
{
public override void PreInitialize()
{
//Add languages for your application
Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flag-england", true));
Configuration.Localization.Languages.Add(new LanguageInfo("tr", "Türkçe", "famfamfam-flag-tr")); //Add a localization source
Configuration.Localization.Sources.Add(
new XmlLocalizationSource(
"SimpleTaskSystem",
HttpContext.Current.Server.MapPath("~/Localization/SimpleTaskSystem")
)
); //Configure navigation/menu
Configuration.Navigation.Providers.Add<SimpleTaskSystemNavigationProvider>();
} public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
abp框架一开始就被设计成模块化的,不同的模块可以通过abp框架来进行配置。举个例子吧,不同的模块都可以添加导航,通过导航添加菜单项到自己定义的主菜单,具体的细节大家可以参照:
本地化:http://www.aspnetboilerplate.com/Pages/Documents/Localization
导航:http://www.aspnetboilerplate.com/Pages/Documents/Navigation
重写内置服务
可以通过Configuration.ReplaceService重写服务,比如可以与您的自定义实现替代iabpsession服务如下图所示:
Configuration.ReplaceService<IAbpSession, MySession>(DependencyLifeStyle.Transient);
replaceservice方法具有过载通过一个自定义的方式进行替换操作。
同样的服务可以被替换多次(特别是在不同的模块)。最后更换将是有效的(你知道,模块分发方法是通过依赖顺序执行)。
配置模块
和.net框架原生的启动配置相比较,abp有哪些不一样呢?abp框架的模块可以通过IAbpModuleConfigurations接口进行个性化的扩展,这样的话,模块配置更加简单、方便。
示例代码如下:
...
using Abp.Web.Configuration;
...
public override void PreInitialize()
{
Configuration.Modules.AbpWeb().SendAllExceptionsToClients = true;
}
...
在上面这个例子中,我们通过配置AbpWeb模块,发送异常到客户端。当然了,不是每一个模块都需要这种配置,通常情况下我们需要,是当一个模块需要在多个不同的应用中重复使用,我们才进行这样的配置。
为一个模块创建配置
如下代码,假如我们有一个命名为MyModule的模块,并且这各模块有一些自己的配置。那么我们首先要创建一些类,这些类定义为属性(译者注:属性有自动的get和set访问器。),代表了不同的配置。
public class MyModuleConfig
{
public bool SampleConfig1 { get; set; } public string SampleConfig2 { get; set; }
}
接下来,我们通过依赖注入,注册这个类。
IocManager.Register<MyModuleConfig>();
最后,我们通过创建一个扩展的方法IModuleConfigurations来得到配置的引用。如下代码:
public static class MyModuleConfigurationExtensions
{
public static MyModuleConfig MyModule(this IModuleConfigurations moduleConfigurations)
{
return moduleConfigurations.AbpConfiguration
.GetOrCreate("MyModuleConfig",
() => moduleConfigurations.AbpConfiguration.IocManager.Resolve<MyModuleConfig>()
);
}
}
现在,在其他模块中也可以配置我们自定义的这个MyModule模块了。
Configuration.Modules.MyModule().SampleConfig1 = false;
Configuration.Modules.MyModule().SampleConfig2 = "test";
在某种意义上,MyModule需要这些配置,你能注射MyModuleConfig并且可以使用这些值。
public class MyService : ITransientDependency
{
private readonly MyModuleConfig _configuration; public MyService(MyModuleConfig configuration)
{
_configuration = configuration;
} public void DoIt()
{
if (_configuration.SampleConfig2 == "test")
{
//...
}
}
}
这意味着,在abp框架的系统中,所有的模块都可以集中配置。
三、ABP核心模块配置分析
ABP的配置设计的非常巧妙,通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配置中心化。配置中心化是一个支持模块开发的框架必备功能。
ABP中核心功能模块中的一些功能的运行时的行为是依赖于一些外部配置的。所以ABP底层框架通过IAbpStartupConfiguration供外部模块自定义Congfiguration。
ABP初始化阶段就要被实例化的接口都放到了Startup文件夹下

ABP核心功能组件的Configuration实例化过程如下图:

以后需要调用或修改某个组件的Configuration,只要引用其IAbpStartupConfiguration的实例Configuration即可访问各个组件的Configuration了。

四、自定义module的Configuration 实现分析
Abp底层框架知道自己核心功能模块,所以就很自然的给每个核心功能模块各自定义一个Configuration接口。但是Abp底层框架并不知道自定义的module有哪些,所以也就无法给每个自定义的module都创建一个Configuration接口。那么ABP底层框架是怎么管理每个自定义的module的Configuration的呢?
仔细看代码,IAbpStartupConfiguration继承了IDictionaryBasedConfig,DictionaryBasedConfig实现了IDictionaryBasedConfig接口,DictionaryBasedConfig下有个dictionary,这个就是最终保存自定义的module的Configuration的地方,因为Configuration的类型未知,所以dictionary的value是object类型。
下面以AbpWebModule为例讲解
1、AbpWebModule定义了自己的接口IAbpWebModuleConfiguration和AbpWebModuleConfiguration,以及AbpConfigurationExtension

2、在AbpWebModule的preInitialize方法中将接口IAbpWebModuleConfiguration和其实现AbpWebModuleConfiguration注册到容器中。
IocManager.Register<IAbpWebModuleConfiguration, AbpWebModuleConfiguration>();
3、AbpConfigurationExtension扩展了IModuleConfigurations接口
using Abp.Web.Configuration; namespace Abp.Configuration.Startup
{
/// <summary>
/// Defines extension methods to <see cref="IModuleConfigurations"/> to allow to configure ABP Web module.
/// </summary>
public static class AbpWebConfigurationExtensions
{
/// <summary>
/// Used to configure ABP Web module.
/// </summary>
public static IAbpWebModuleConfiguration AbpWeb(this IModuleConfigurations configurations)
{
return configurations.AbpConfiguration.GetOrCreate("Modules.Abp.Web", () => configurations.AbpConfiguration.IocManager.Resolve<IAbpWebModuleConfiguration>());
}
}
}
这个接口是在Abp底层框架中定义和实现的。其属性AbpConfiguration就是AbpStartupConfiguration实例。通过AbpStartupConfiguration的getorCreate方法(具体通过DictionaryBasedConfig来实现)就可以获取到AbpWebModule自定义的AbpWebModuleConfiguration的实例了。
namespace Abp.Configuration.Startup
{
internal class ModuleConfigurations : IModuleConfigurations
{
public IAbpStartupConfiguration AbpConfiguration { get; private set; } public ModuleConfigurations(IAbpStartupConfiguration abpConfiguration)
{
AbpConfiguration = abpConfiguration;
}
}
}
具体访问方式如下,Configuration.Modules就是IModuleConfigurations的实例。通过其扩展方法AbpWeb访问AbpWebModuleConfiguration
Configuration.Modules.AbpWeb.SendAllExceptionsToClients=True;
基于DDD的.NET开发框架 - ABP启动配置的更多相关文章
- 线上分享-- 基于DDD的.NET开发框架-ABP介绍
前言 为了能够帮助.Net开发者开拓视野,更好的把最新的技术应用到工作中,我在3月底受邀到如鹏网.net训练营直播间为各位学弟学妹们进行ABP框架的直播分享.同时为了让更多的.NET开发者了解ABP框 ...
- 基于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初探
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 基于DDD的.NET开发框架ABP实例,多租户 (Sass)应用程序,采用.NET MVC, Angularjs, EntityFramework-介绍
介绍 基于ABPZERO的多租户 (Sass)应用程序,采用ASP.NET MVC, Angularjs-介绍 ASP.NET Boilerplate作为应用程序框架. ASP.NET MVC和ASP ...
- 基于DDD的.NET开发框架ABP实例,多租户 (Saas)应用程序,采用.NET MVC, Angularjs, EntityFramework-介绍
介绍 基于ABPZERO的多租户 (Saas)应用程序,采用ASP.NET MVC, Angularjs-介绍 ASP.NET Boilerplate作为应用程序框架. ASP.NET MVC和ASP ...
- 基于DDD的.NET开发框架 - ABP的Entity设计思想
返回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应 ...
- 基于DDD的.NET开发框架 - ABP日志Logger集成
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
随机推荐
- 十五天精通WCF——第七天 Close和Abort到底该怎么用才对得起观众
一:文起缘由 写这一篇的目的源自于最近看同事在写wcf的时候,用特别感觉繁琐而且云里雾里的嵌套try catch来防止client抛出异常,特别感觉奇怪,就比如下面的代码. public void S ...
- SQLServer基本函数
1.字符串函数 长度与分析用 datalength(Char_expr) 返回字符串包含字符数,但不包含后面的空格 substring(expression,start,length) 取子串 ri ...
- RabbitMq 技术文档
RabbitMq 技术文档 目录 1 AMQP简介 2 AMQP的实现 3 RabbitMQ简介 3.1 概念说明 3.2 消息队列的使用过程 3.3 RabbitMQ的特性 4 RabbitMQ使用 ...
- Linux信号类型说明
说明 在Linux系统开发中经常要使用到信号来实现异步通知机制.而在Linux系统中信号有很多种,也不用全部记住,学习几种常见的信号,学会使用即可:当然也要知道用哪种方式能够发送这样的信号. 查看li ...
- Linux系统管理命令之用户组管理
涉及的配置文件 /etc/group /etc/gshadow /etc/gshadow- 可用于还原 不同系统的备份文件名称不同:name-或name.old 命令: 添加用户组groupadd 组 ...
- 利用NuSoap开发WebService(PHP)
利用NuSoap开发WebService(PHP) 分类: php 2010-09-08 12:00 5005人阅读 评论(1) 收藏 举报 webservicephpsoapstringencodi ...
- ResultSet rs = stmt.executeQuery(sql); 返回值问题判断
JAVA ResultSet rs = stmt.executeQuery(sql); //查询返回的结果集不管是否查到,rs都不是null,那么问题是怎么判断查找不到来执行一个提示“账号或者 ...
- hdu 4960 Another OCD Patient(dp)
Another OCD Patient Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Ot ...
- Spring AOP 开发中遇到问题:Caused by: java.lang.IllegalArgumentException: warning no match for this type name: com.xxx.collector.service.impl.XxxServiceImpl [Xlint:invalidAbsoluteTypeName]
在网上找了很多,都不是我想要的,后来发现是我在springaop注解的时候 写错了类名导致的这个问题 @Pointcut("execution(* com.xxx.collector.ser ...
- cloudera cdh native lib
如果通过命令行的方式安装cloudera 版本的hadoop,下载它的cdh版本. 解压后执行,你会发现报warning,没有native的库,lib/native是空的. 如何获取native的文件 ...