下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、ABP框架的基础配置及依靠注入讲解_ 这篇文章主要介绍了ABP框架的基础配置及依靠注入讲解,是ABP框架上手用法的基本,要的伴侣可以参考下 配置ABP 配置是通过在自己模块的PreInitialize方法中来实现的 代码示例如下: public class SimpleTaskSystemModule : AbpModule public override void PreInitialize() /在你的应用中添加语言包,这个是英语和的土耳其语。 Configuration.Localization.Languages.Add(new LanguageInfo(en, English, fa
2、mfamfam-flag-england, true); Configuration.Localization.Languages.Add(new LanguageInfo(tr, Trke, famfamfam-flag-tr); Configuration.Localization.Sources.Add( new XmlLocalizationSource( SimpleTaskSystem, HttpContext.Current.Server.MapPath(/Localization/SimpleTaskSystem) ) ); /配置导航和菜单 Configuration.Nav
3、igation.Providers.AddSimpleTaskSystemNavigationProvider(); public override void Initialize() IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly(); 和orchard类似,abp框架一开头就被设计成模块化的,不同的模块可以通过abp框架来进行配置。举个例子吧,不同的模块都可以添加导航,通过导航添加菜单项到自己定义的主菜单,具体的详情大家可以参照: 本地化: 导航: 配置模块 和.net框架原生的启动配置相比较,ab
4、p有哪些不一样呢?abp框架的模块可以通过IAbpModuleConfigurations接口进行共性化的扩展,这样的话,模块配置更加简洁、便利。 示例代码如下: . using Abp.Web.Configuration; . public override void PreInitialize() Configuration.Modules.AbpWeb().SendAllExceptionsToClients = true; . 在上面这个例子中,我们通过配置AbpWeb模块,发送特别到客户端。当然了,不是每一个模块都需要这种配置,通常状况下我们需要,是当一个模块需要在多个不同的应用中重
5、复用法,我们才进行这样的配置。 为一个模块创建配置 如下代码,假如我们有一个命名为MyModule的模块,并且这各模块有一些自己的配置。那么我们首先要创建一些类,这些类定义为属性(译者注:属性有自动的get和set访问器。),代表了不同的配置。 public class MyModuleConfig public bool SampleConfig1 get; set; public string SampleConfig2 get; set; 接下来,我们通过依靠注入,注册这个类。 IocManager.RegisterMyModuleConfig(); /译者注:在IocManager中注
6、册了一个类,换句话说,我们通过IocManager可以得到这个类MyModuleConfig的实例。至于IOC的原理这里就不在具体说了,总之,就是可以得到一个类的实例。 最终,我们通过创建一个扩展的方法IModuleConfigurations来得到配置的引用。如下代码: 2021615173022790.png (920215) 译者注:模块配置是一个静态类,由于我们需要重复用法它。静态方法Mymodule返回的是一个配置接口,参数是ImoduleConfigurations接口。 现在,在其他模块中也可以配置我们自定义的这个MyModule模块了。 Configuration.Module
7、s.MyModule().SampleConfig1 = false; Configuration.Modules.MyModule().SampleConfig2 = test; 在某种意义上,MyModule需要这些配置,你能注射MyModuleConfig并且可以用法这些值。 public class MyService : ITransientDependency private readonly MyModuleConfig _configuration; public MyService(MyModuleConfig configuration) _configuration =
8、configuration; public void DoIt() if (_configuration.SampleConfig2 = test) /. 这意味着,在abp框架的系统中,全部的模块都可以集中配置。 ABP依靠注入 什么是依靠注入 假如你已经知道依靠注入的概念,构造函数和属性注入模式,你可以跳过这一节。 维基百科说:“依靠注入是一种软件设计模式的一个或多个依靠项注入(或服务),或通过引用传递,为依靠对象(或客户)和客户端状态的一部分。模式之间建立一个客户的依靠关系的行为,它允许程序设计是松散耦合的,依靠倒置和单一职责原则。它挺直对比service locator模式,它允许客户
9、了解他们所用法的系统找到依靠。”。 假如不用法依靠注入技术,很难进行依靠管理、模块化开发和应用程序模块化。 传统方式的问题 在一个应用程序中,类之间相互依靠。假设我们有一个应用程序服务,用法仓储(repository)类插入实体到数据库。在这种状况下,应用程序服务类依靠于仓储(repository)类。看下例子: public class PersonAppService private IPersonRepository _personRepository; public PersonAppService() _personRepository = new PersonRepository(
10、); public void CreatePerson(string name, int age) var person = new Person Name = name, Age = age ; _personRepository.Insert(person); PersonAppService用法PersonRepository插入Person到数据库。这段代码的问题: PersonAppService通过IPersonRepository调用CreatePerson方法,所以这方法依靠于IPersonRepository,代替了PersonRepository具体类。但PersonApp
11、Service(的构造函数)仍旧依靠于PersonRepository。组件应当依靠于接口而不是实现。这就是所谓的依靠性倒置原则。 假如PersonAppService创建PersonRepository本身,它成为依靠IPersonRepository接口的具体实现,不能用法另一个实现。因此,此方式的将接口与实现分别变得毫无意义。硬依靠(hard-dependency)使得代码紧密耦合和较低的可重用。 我们可能需要在将来转变创建PersonRepository的方式。即,我们可能想让它创建为单例(单一共享实例而不是为每个用法创建一个对象)。或者我们可能想要创建多个类实现IPersonRepo
12、sitory并依据条件创建对象。在这种状况下,我们需要修改全部依靠于IPersonRepository的类。 有了这样的依靠,很难(或不行能)对PersonAppService进行单元测试。 为了克服这些问题,可以用法工厂模式。因此,创建的仓储类是抽象的。看下面的代码: public class PersonAppService private IPersonRepository _personRepository; public PersonAppService() _personRepository = PersonRepositoryFactory.Create(); public vo
13、id CreatePerson(string name, int age) var person = new Person Name = name, Age = age ; _personRepository.Insert(person); PersonRepositoryFactory是一个静态类,创建并返回一个IPersonRepository。这就是所谓的服务定位器模式。以上依靠问题得到解决,由于PersonAppService不需要创建一个IPersonRepository的实现的对象,这个对象取决于PersonRepositoryFactory的Create方法。但是,仍旧存在一些问
14、题: 此时,PersonAppService取决于PersonRepositoryFactory。这是更简单接受,但仍有一个硬依靠(hard-dependency)。 为每个库或每个依靠项乏味的写一个工厂类/方法。 测试性依旧不好,由于很难使得PersonAppService用法mock实现IPersonRepository。 解决方案: 有一些最佳实践(模式)用于类依靠。 构造函数注入 重写上面的例子,如下所示: public class PersonAppService private IPersonRepository _personRepository; public PersonAp
15、pService(IPersonRepository personRepository) _personRepository = personRepository; public void CreatePerson(string name, int age) var person = new Person Name = name, Age = age ; _personRepository.Insert(person); 这被称为构造函数注入。现在,PersonAppService不知道哪些类实现IPersonRepository以及如何创建它。谁需要用法PersonAppService,首先
16、创建一个IPersonRepository PersonAppService并将其传递给构造函数,如下所示: var repository = new PersonRepository(); var personService = new PersonAppService(repository); personService.CreatePerson(Yunus Emre, 19); 构造函数注入是一个完善的方法,使一个类独立创建依靠对象。但是,上面的代码有一些问题: 创建一个PersonAppService变得困难。想想假如它有4个依靠,我们必需创建这四个依靠对象,并将它们传递到构造函数Pe
17、rsonAppService。 从属类可能有其他依靠项(在这里,PersonRepository可能有依靠关系)。所以,我们必需创建PersonAppService的全部依靠项,全部依靠项的依靠关系等等. .如此,依靠关系使得我们创建一个对象变得过于简单了。 幸运的是,依靠注入框架自动化管理依靠关系。 属性注入 构造函数注入模式是一个完善的供应类的依靠关系的方式。通过这种方式,您不能创建类的实例,而不供应依靠项。它也是一个强大的方式显式地声明是什么类的需求正确地工作。 但是,在某些状况下,该类依靠于另一个类,但也可以没有它。这通常是适用于横切关注点(如日志记录)。一个类可以没有工作日志,但它可
18、以写日志假如你供应一个日志对象。在这种状况下,您可以定义依靠为公共属性,而不是让他们放在构造函数。想想,假如我们想在PersonAppService写日志。我们可以重写类如下: public class PersonAppService public ILogger Logger get; set; private IPersonRepository _personRepository; public PersonAppService(IPersonRepository personRepository) _personRepository = personRepository; Logger
19、 = NullLogger.Instance; public void CreatePerson(string name, int age) Logger.Debug(Inserting a new person to database with name = + name); var person = new Person Name = name, Age = age ; _personRepository.Insert(person); Logger.Debug(Successfully inserted!); NullLogger.Instance 是一个单例对象,实现了ILogger接
20、口,但事实上什么都没做(不写日志。它实现了ILogger实例,且方法体为空)。现在,PersonAppService可以写日志了,假如你为PersonAppService实例设置了Logger,如下面: var personService = new PersonAppService(new PersonRepository(); personService.Logger = new Log4NetLogger(); personService.CreatePerson(Yunus Emre, 19); 假设Log4NetLogger实现ILogger实例,使得我们可以用法Log4Net库写日
21、志。因此,PersonAppService可以写日志。假如我们不设置Logger,PersonAppService就不写日志。因此,我们可以说PersonAppService ILogger实例是一个可选的依靠。 几乎全部的依靠注入框架都支持属性注入模式 依靠注入框架 有很多依靠注入框架,都可以自动解决依靠关系。他们可以创建全部依靠项(递归地依靠和依靠关系)。所以你只需要依据注入模式写类和类构造函数属性,其他的交给DI框架处理!在良好的应用程序中,类甚至独立于DI框架。整个应用程序只会有几行代码或类,显示的与DI框架交互。 ABP的依靠注入基于 Castle Windsor框架。Castle
22、Windsor最成熟的DI框架之一。还有许多这样的框架,如Unity,Ninject,StructureMap,Autofac等等。 在用法一个依靠注入框架时,首先注册您的接口/类到依靠注入框架中,然后你就可以resolve一个对象。在Castle Windsor,它是这样的: var container = new WindsorContainer(); container.Register( Component.ForIPersonRepository().ImplementedByPersonRepository().LifestyleTransient(), Component.For
23、IPersonAppService().ImplementedByPersonAppService().LifestyleTransient() ); var personService = container.ResolveIPersonAppService(); personService.CreatePerson(Yunus Emre, 19); 我们首先创建了WindsorContainer。然后注册PersonRepository 和 PersonAppService及它们的接口。然后我们要求容器创建一个IPersonAppService实例。它创建PersonAppService对
24、象及其依靠项并返回。在这个简洁的示例中,用法DI框架或许不是那么简洁,但想象下,在实际的企业应用程序中你会有许多类和依靠关系。当然,注册的依靠项只在程序启动的某个地方创建一次。 请留意,我们只是讲对象声明为临时对象(transient)。这意味着每当我们创建这些类型的一个对象时,就会创建一个新的实例。有很多不同的生命周期(如Singletion)。 ABP依靠注入的基础结构 在编写应用程序时遵循最佳实践和一些商定,ABP几乎让依靠注入框架用法变得无形。 注册: 在ABP中,有许多种不同的方法来注册你的类到依靠注入系统。大部分时间,常规方法就足够了。 常规注册: 根据商定,ABP自动注册全部 R
25、epositories, Domain Services, Application Services, MVC 掌握器和Web API掌握器。例如,您可能有一个IPersonAppService 接口和实现类PersonAppService: public interface IPersonAppService : IApplicationService /. public class PersonAppService : IPersonAppService /. ABP会自动注册它,由于它实现IApplicationService接口(它只是一个空的接口)。它会被注册为transient (
26、每次用法都创建实例)。当你注入(用法构造函数注入)IPersonAppService接口成一个类,PersonAppService对象会被自动创建并传递给构造函数。 命名商定在这里特别重要。例如你可以将名字PersonAppService改为 MyPersonAppService或另一个包含“PersonAppService”后缀的名称,由于IPersonAppService包含这个后缀。但是你可以不遵循PeopleService命名您的服务类。假如你这样做,它将不会为IPersonAppService自动注册(它需要自注册(self-registration)到DI框架,而不是接口),所以,
27、假如你想要你应当手动注册它。 ABP根据商定注册程序集。所以,你应当告诉ABP根据商定注册您的程序集。这很简单: IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly(); Assembly.GetExecutingAssembly()得到一个对包括此代码的程序集的引用。你可以通过RegisterAssemblyByConvention方法注册其他程序集。这同在你的模块初始化(AbpModule.Initialize())时完成。请查看ABP的模块系统获得更多信息。 您可以通过实现IConventionalR
28、egisterer接口和调用IocManager。AddConventionalRegisterer方法编写自己的商定注册类。你应当将它添加到模块的pre-initialize方法中。 关心接口 你可以注册一个特定的类,不遵循传统的商定制度规章。ABP供应了ITransientDependency和ISingletonDependency接口的快捷方法。例如: public interface IPersonManager /. public class MyPersonManager : IPersonManager, ISingletonDependency /. 以这种方式,您可以很简单
29、地注册MyPersonManager为transient。当需要注入IPersonManager时,MyPersonManager会被用法。留意,依靠被声明为单例。因此,创建的MyPersonManager同一个对象被传递给全部需要的类。只是在第一次用法时创建,那么应用程序的整生命周期用法的是同一实例。 自定义/挺直 注册 假如之前描述的方法还是不足以应对你的状况,你可以用法Castle Windsor注册类和及依靠项。因此,您将拥有Castle Windsor注册的全部力量。 可以实现IWindsorInstaller接口进行注册。您可以在应用程序中创建一个实现IWindsorInstall
30、er接口的类: public class MyInstaller : IWindsorInstaller public void Install(IWindsorContainer container, IConfigurationStore store) container.Register(Classes.FromThisAssembly().BasedOnIMySpecialInterface().LifestylePerThread().WithServiceSelf(); Abp自动发觉和执行这个类。最终,你可以通过用法IIocManager.IocContainer属性得到Wind
31、sorContainer。有关更多信息,阅读Windsor的文档。 解析(Resolving) 注册通知IOC(掌握反转)容器关于你的类,它们的依靠项和生命周期。在您的应用程序需要用法IOC容器创建对象时,ASP.NET供应了一些方法解决依靠关系。 构造函数 属性注入 作为最佳实践,你可以用法构造函数和属性注入去猎取你的类的依靠。任何可能的地方,你都应当这样做。例子: public class PersonAppService public ILogger Logger get; set; private IPersonRepository _personRepository; public
32、PersonAppService(IPersonRepository personRepository) _personRepository = personRepository; Logger = NullLogger.Instance; public void CreatePerson(string name, int age) Logger.Debug(Inserting a new person to database with name = + name); var person = new Person Name = name, Age = age ; _personReposit
33、ory.Insert(person); Logger.Debug(Successfully inserted!); IPersonRepository从构造函数注入,ILogger实例从公共属性注入。这样,您的代码不会体现依靠注入系统。这是用法DI系统最适当的方式。 IIocResolver 和 IIocManager 有时你可能需要挺直创建你的依靠项,而不是构造函数和属性注入。应当尽可能避开这种状况,但它可能无法避开。Abp供应一些服务使得这样的注入很简单实现。例子: public class MySampleClass : ITransientDependency private readonly IIocResolver _iocResolver; public MySampleClass(IIocResolver iocResolver) _iocResolver = iocResolver; public void DoIt() /Resolving, using and releasing manually var personService1 = _iocResolver.ResolvePersonAppServic
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中国石化环保策略的规划助理指南
- 电商仓储物流岗位招聘流程及面试要点详解
- 金融投资经理面试全攻略及知识
- 2025-2026学年四川省绵阳市北川县永昌中学四校联考七年级(下)开学英语试卷(含答案)
- 任务2-2 简单声光报警器的制作
- 勾股定理及其应用(第2课时)课件2025-2026学年人教版数学八年级下册
- 第10单元 课题3 第3课时 盐的化学性质 化肥 教学设计2025-2026九年级化学人教版下册
- 重庆商务职业学院2025年考核招聘事业单位工作人员38名备考题库(第二批)带答案详解
- 2025年慈溪市上林人才服务有限公司公开招聘安全生产服务项目派遣制辅助管理人员备考题库完整答案详解
- 2025年福州市中医院第三次调整自主招聘工作人员9人备考题库及参考答案详解
- 水利水电工程自动化技术试题及答案
- 《医疗机构药学服务课件》
- 学校内部控制制度培训
- 便利店食品安全管理制度
- 放射医学辐射安全培训
- 食堂经理工作年终总结
- 未成年人保护法普法宣传教育课件
- (一诊)2025年兰州市高三诊断考试英语试卷(含官方答案)
- 农村修水渠合同范本
- 《普通动物学绪论》课件
- 全套电子课件:数控机床电气装调与维修
评论
0/150
提交评论