ABP项目中的使用AutoMapper
AutoMapper之ABP项目中的使用
最近在研究ABP项目,昨天写了Castle Windsor常用介绍以及其在ABP项目的应用介绍 欢迎各位拍砖,有关ABP的介绍请看阳光铭睿 博客
AutoMapper只要用来数据转换,在园里已经有很多这方面文章了,本文主要介绍其在实际项目常用总结,以及在ABP项目中的应用介绍。AutoMapper应用非常简单,大家稍微看下文档就可以上手,但是性能不好啊,所以一般用在后台项目,对外的项目千万不要用。就那NOP来说吧,它也是把AutoMapper放在后台项目使用,商城前台的项目是不敢用的。
有关性能的问题本文没有涉及到,想了解的请参考EmitMapper,AutoMapper,NLiteMapper和手工映射性能大比拼 和 NLiteMapper与EmitMapper性能简单比较。
下面主要讲下项目的入门和项目中的使用。
AutoMapper使用只要两步,配置和Mapper,一般的在项目中我们会在Global中进行配置
配置映射关系
|
1
2
3
4
5
6
7
8
9
10
11
12
|
public class Source{ public int SomeValue { get; set; }}public class Destination{ public int SomeValue { get; set; }}//这个就是配置映射关系Mapper.CreateMap<Source, Destination>(); |
然后就是Mapper
|
1
2
3
4
5
6
7
|
Source source = new Source(){ SomeValue = 1};var destination = Mapper.Map<Source, Destination>(source);Console.WriteLine(destination.SomeValue);//1 |
是不是很简单,这是最简单的使用了,当然AutoMapper是个“机关枪”,这个只是它的最简单使用。下面在介绍几点常用的功能。还是上面那个例子,只是字段变了
|
1
2
3
4
5
6
7
8
9
10
11
|
public class Source{ public int SomeValue { get; set; }}public class Destination{ public int SomeValuefff { get; set; }}Mapper.CreateMap<AddressDto, Address>(); |
这样子字段都不一样明细是不能映射的嘛,所有呢我们可以用Mapper.AssertConfigurationIsValid()来验证,就会AutoMapperConfigurationException异常,
选择忽略相关字段
|
1
2
|
Mapper.CreateMap<Source, Destination>() .ForMember(dest => dest.SomeValuefff, opt => opt.Ignore()); |
类型转换,自定义类型转换
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class Source{ public string Value1 { get; set; } public string Value2 { get; set; } public string Value3 { get; set; }}public class Destination{ public int Value1 { get; set; } public DateTime Value2 { get; set; } public Type Value3 { get; set; }} |
Source要转Destination,但是第二和第三的字段类型都不一致,所以我们可以自定义类型转换,下面看下转换函数ConvertUsing一般最常用第二种,接受一个ITypeConverter
|
1
2
3
|
void ConvertUsing(Func<TSource, TDestination> mappingFunction);void ConvertUsing(ITypeConverter<TSource, TDestination> converter);void ConvertUsing<TTypeConverter>() where TTypeConverter : ITypeConverter<TSource, TDestination>; |
下面看下ITypeConverter接口
|
1
2
3
4
|
public interface ITypeConverter<TSource, TDestination>{ TDestination Convert(ResolutionContext context);} |
我们可以继承这个接口队Convert进行重写
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class DateTimeTypeConverter : ITypeConverter<string, DateTime>{ public DateTime Convert(ResolutionContext context) { return System.Convert.ToDateTime(context.SourceValue); }}public class TypeTypeConverter : ITypeConverter<string, Type>{ public Type Convert(ResolutionContext context) { return context.SourceType; }} |
这样我们就可以映射了,下面看下完整代码
好了,上面把 AutoMapper在项目中常用的方法都介绍完了,再介绍ABP之前我们先看下NOP是怎么使用的吧,由于代码较长省略部分
好了,终于可以到ABP的了,ABP对AutoMapper的使用总结出来两点,1、在模块中初始化配置,2、遍历bin目录下所有的Types判断哪些类是否被定义为需要转换的Attribute
在模块中初始化配置
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class AbpAutoMapperModule : AbpModule{ private readonly ITypeFinder _typeFinder; private static bool _createdMappingsBefore; private static readonly object _syncObj = new object(); public AbpAutoMapperModule(ITypeFinder typeFinder) { _typeFinder = typeFinder; } private void FindAndAutoMapTypes() { var types = _typeFinder.Find(type => type.IsDefined(typeof(AutoMapAttribute)) || type.IsDefined(typeof(AutoMapFromAttribute)) || type.IsDefined(typeof(AutoMapToAttribute)) ); foreach (var type in types) { AutoMapperHelper.CreateMap(type); } }} |
AbpAutoMapperModule 模块会在Global的时候被初始化,然后在PreInitialize的时候回调用到FindAndAutoMapTypes,有关模块是怎么初始化的我想再写一篇介绍。下面我们看下_typeFinder吧
上面_typeFinder.Find调用的是TypeFinder的Find方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
public Type[] Find(Func<Type, bool> predicate){ return GetAllTypes().Where(predicate).ToArray();}public Type[] FindAll(){ return GetAllTypes().ToArray();}private List<Type> GetAllTypes(){ var allTypes = new List<Type>(); foreach (var assembly in AssemblyFinder.GetAllAssemblies().Distinct()) { try { Type[] typesInThisAssembly; try { typesInThisAssembly = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { typesInThisAssembly = ex.Types; } if (typesInThisAssembly.IsNullOrEmpty()) { continue; } allTypes.AddRange(typesInThisAssembly.Where(type => type != null)); } catch (Exception ex) { Logger.Warn(ex.ToString(), ex); } } return allTypes;} |
好吧,上面代码有点多,但是很简单,就是获取所有的Types,我们看下关键代码AssemblyFinder.GetAllAssemblies()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class WebAssemblyFinder : IAssemblyFinder{ /// <summary> /// This return all assemblies in bin folder of the web application. /// </summary> /// <returns>List of assemblies</returns> public List<Assembly> GetAllAssemblies() { var assembliesInBinFolder = new List<Assembly>(); var allReferencedAssemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList(); var dllFiles = Directory.GetFiles(HttpRuntime.AppDomainAppPath + "bin\\", "*.dll", SearchOption.TopDirectoryOnly).ToList(); foreach (string dllFile in dllFiles) { var locatedAssembly = allReferencedAssemblies.FirstOrDefault(asm => AssemblyName.ReferenceMatchesDefinition(asm.GetName(), AssemblyName.GetAssemblyName(dllFile))); if (locatedAssembly != null) { assembliesInBinFolder.Add(locatedAssembly); } } return assembliesInBinFolder; }} |
看看吧,这代码是或bin目录下面的dll,好丧心病狂啊,回到刚刚AbpAutoMapperModule 的获取FindAndAutoMapTypes方法。在获取所有的Types之后我们就要判断这个类是否是被标识了
AutoMapAttribute、AutoMapFromAttribute和AutoMapToAttribute
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
private void FindAndAutoMapTypes(){ var types = _typeFinder.Find(type => type.IsDefined(typeof(AutoMapAttribute)) || type.IsDefined(typeof(AutoMapFromAttribute)) || type.IsDefined(typeof(AutoMapToAttribute)) ); foreach (var type in types) { AutoMapperHelper.CreateMap(type); }} |
获取之后再我下的Demo中就只有一个UserDto类被标识了
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
namespace AbpDemo.Application.Users.Dto{ [AutoMapFrom(typeof(User))] public class UserDto : EntityDto<long> { public string UserName { get; set; } public string Name { get; set; } public string Surname { get; set; } public string EmailAddress { get; set; } }} |
接下来就是遍历所有的types进行配置了AutoMapperHelper.CreateMap(type);配置也很简单 看下代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public static void CreateMap<TAttribute>(Type type) where TAttribute : AutoMapAttribute{ if (!type.IsDefined(typeof (TAttribute))) { return; } foreach (var autoMapToAttribute in type.GetCustomAttributes<TAttribute>()) { if (autoMapToAttribute.TargetTypes.IsNullOrEmpty()) { continue; } foreach (var targetType in autoMapToAttribute.TargetTypes) { if (autoMapToAttribute.Direction.HasFlag(AutoMapDirection.To)) { Mapper.CreateMap(type, targetType); } if (autoMapToAttribute.Direction.HasFlag(AutoMapDirection.From)) { Mapper.CreateMap(targetType, type); } } }} |
好了,表达能力不是很好,各位就勉强看下吧。终于写完了。发现作者很喜欢用Attribute来过滤。这边AutoMapper是这样,UnitOfWork也是这样,其实这样也是挺方便的,有点AOP的切面的感觉,值得学习。
参考文章:
http://www.cnblogs.com/netcasewqs/archive/2011/04/13/2014684.html
http://www.cnblogs.com/repository/archive/2011/04/08/2009713.html
https://github.com/AutoMapper/AutoMapper/wiki/Configuration-validation
http://www.cnblogs.com/youring2/p/automapper.html
http://www.cnblogs.com/1-2-3/p/AutoMapper-Best-Practice.html
ABP项目中的使用AutoMapper的更多相关文章
- AutoMapper之ABP项目中的使用介绍
最近在研究ABP项目,昨天写了Castle Windsor常用介绍以及其在ABP项目的应用介绍 欢迎各位拍砖,有关ABP的介绍请看阳光铭睿 博客 AutoMapper只要用来数据转换,在园里已经有很多 ...
- 说说ABP项目中的AutoMapper,Castle Windsor(痛并快乐着)
这篇博客要说的东西跟ABP,AutoMapper和Castle Windsor都有关系,而且也是我在项目中遇到的问题,最终解决了,现在的感受就是“痛并快乐着”. 首先,这篇博客不是讲什么新的知识点,而 ...
- ABP项目中使用Swagger生成动态WebAPI
本文是根据角落的白板报的<使用ABP实现SwaggerUI,生成动态webapi>一文的学习总结,感谢原文作者角落的白板报. 1 安装Swashbuckle.core 1.1 选择WebA ...
- 在基于AngularJs架构的ABP项目中使用UEditor
[前提须知] 读过此篇博客 了解angular-ueditor 了解ABP如何使用 会使用VS2017 [1.下载ABP模板] https://aspnetboilerplate.com/Templa ...
- Abp项目中的领域模型实体类访问仓储的方法
首先声明,不推荐使用这种方法.实体访问仓储是不被推荐的! 1.简单粗暴的方法 Abp.Dependency.IocManager.Instance.Resolve>(); 2.绕个弯子的方法 首 ...
- abp项目中无法使用HttpContext.Current.Session[""]的问题
web项目Global.asax.cs中加入如下代码 public override void Init() { this.PostAuthenticateRequest += (sender, e) ...
- AutoMapper在ABP框架中的使用说明
为了说明AutoMapper如何使用,我专门开设了一个专题来讲,如果您还没有查看该专题,请点击这里.既然系统地学习了AutoMapper,那么接下来就是该用它实战的时候了.今天,我们就来揭开AutoM ...
- 在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射
一.前言 在实际项目开发过程中,我们使用到的各种 ORM 组件都可以很便捷的将我们获取到的数据绑定到对应的 List<T> 集合中,因为我们最终想要在页面上展示的数据与数据库实体类之间可能 ...
- Castle Windsor常用介绍以及其在ABP项目的应用介绍
最近在研究ABP项目,有关ABP的介绍请看阳光铭睿 博客,ABP的DI和AOP框架用的是Castle Windsor下面就对Castle Windsor项目常用方法介绍和关于ABP的使用总结 1.下载 ...
随机推荐
- C语言 cgi(2)
1Columbia Universitycs3157 – Advanced ProgrammingSummer 2014, Lab #3, 40 pointsJune 10, 2014This lab ...
- UML之轻松入门(3)-SRP做好厨子,让别人编程去吧
一个厨子能够做出一手好菜,或许他是新东方毕业的或者是祖传秘方.你让他做上一桌佳肴那是简单.快乐而又高效的,然而让他编程就会成为一种苦恼并且让人想不通的一件事.或许这个比喻不是非常恰当,可是对 ...
- 点击 下载 pdf
<iframe id="fileDownFrame" src="" style="display:none; visibility:hidde ...
- 读懂IL
读懂IL 先说说学IL有什么用,有人可能觉得这玩意平常写代码又用不上,学了有个卵用.到底有没有卵用呢,暂且也不说什么学了可以看看一些语法糖的实现,或对.net理解更深一点这些虚头巴脑的东西.最重要的理 ...
- [Windows Phone] 地图控制项的经纬度
原文:[Windows Phone] 地图控制项的经纬度 前言 本文主要示范如何使用地图经纬度以及显示地标和行人街道,并透过卷轴控制地图缩放比例的功能. ? 实作 step1 建立专案. ? step ...
- Socket规划(1)
socket定义 于Linux网络编程是通过socket进行的. 人们常说的socket是一种特殊的I/O接口,他也是一个文件描写叙述符.socket是一种经常使用的进程之间通信机制,通过它不仅能实现 ...
- js+html+css简单的互动功能页面(2015知道几乎尖笔试题)http://v.youku.com/v_show/id_XMTI0ODQ5NTAyOA==.html?from=y1.7-1.2
js+html+css实现简单页面交互功能(2015知乎前端笔试题) http://v.youku.com/v_show/id_XMTI0ODQ5NTAyOA==.html? from=y1.7-1. ...
- unity3D实际的原始视频游戏开发系列讲座12之U3D的2D为了开发实战的新方法
U3D的2D为了开发实战的新方法 (Unity3d-4.x的打飞机2D游戏开发新的方法应用 ) 大纲介绍:不使用NGUI和TK2d插件, 使用 U3D内置强大的最大的工具. 开发过程设计到例 ...
- Tuxedo学习门户网站
中间件简介: 介于客户机和server之间的夹层,突破了传统的c/s架构,为构建大规模,高性能.分布式c/s应用程序提供了通信.事物,安全.容错等基础服务,屏蔽了底层应用细节,应用程序不必从底层开发, ...
- c++分割字符串(类似于boost::split)
由于c++字符串没有split函数,所以字符串分割单词的时候必须自己手写,也相当于自己实现一个split函数吧! 如果需要根据单一字符分割单词,直接用getline读取就好了,很简单 #include ...