最近在使用DDD重新搭建公司内部OA的架构,具体情况搭好了应该会写一下,这里说的是今天遇到的问题。

  先简单说一下相关的几个部分:

  1.聚合。聚合分成了两个模块:一个包含审批单据等估计至少今年不会怎么变的抽象模型;另外一个包含不同审批单据的实现类,继承至抽象的模块;由于主要是要说这一块,就贴一点部分代码上来,与本随笔要说的无关的部分就省略号了。。。

  [DomainAttribute(DomainType = ApplyDomainType.Root, Description = "申请单")]
public class RequisitionBase
{
internal int ID { get; set; }
internal string ProcesssCode { get; set; } /// <summary>
/// 流程类型,定义流程类型,例如“TB”,“HT”等
/// </summary>
internal string ProcessType { get; set; } /// <summary>
/// 申请人域帐号
/// </summary>
internal string ApplicantUserID { get; set; } /// <summary>
/// 申请人姓名
/// </summary>
internal string ApplicantUserName { get; set; } /// <summary>
/// 申请日期
/// </summary>
internal DateTime ApplicantDate { get; set; } //还有一些属性和方法,不过都不重要了
}
    public class AllographRequisition : RequisitionBase
{
public AllographRequisition()
{
//代签项目申请单实现类,略。。。
}
}

  2.用于UI和应用层之间传数据的DTO,命名应该用信息的,不过咱纯粹的不愿意用那个单词。。。

    public class AllographRequisitionData
{
//方便测试
public AllographRequisitionData(AllographRequisitionData data)
{
Project = data.Project;
RequisitionContent = data.RequisitionContent;
} public AllographRequisitionData(ProjectContentData project, AllographRequisitionContentData requisitionContent)
{
Project = project;
RequisitionContent = requisitionContent;
} public ProjectContentData Project { get; set; }
public AllographRequisitionContentData RequisitionContent { get; set; } public int ID { get; set; }
public string ProcesssCode { get; set; } /// <summary>
/// 流程类型,定义流程类型,例如“TB”,“HT”等
/// </summary>
public string ProcessType { get; set; } /// <summary>
/// 申请人域帐号
/// </summary>
public string ApplicantUserID { get; set; } /// <summary>
/// 申请人姓名
/// </summary>
public string ApplicantUserName { get; set; } /// <summary>
/// 申请日期
/// </summary>
public DateTime ApplicantDate { get; set; } //一些属性。。。
}

  3.应用服务,这随笔发生的地方,DTO与聚合映射的所在,只是个简单的意思,不要太在意

        public AllographRequisition DataToEntity(AllographRequisitionData data)
{
Mapper.CreateMap<AllographRequisitionData, AllographRequisition>(); AllographRequisition requisition
= Mapper.Map<AllographRequisitionData, AllographRequisition>(data);
DateTime date = requisition.ApplicantDate;
return requisition;
}

  4.单元测试,因为应用层咱是用TDD开始的。。。

        [TestMethod]
public void Save()
{
RequisitionService service = new RequisitionService();
AllographRequisitionData t = new AllographRequisitionData(service.GetTestData());
t.ApplicantDate = DateTime.Now;
var data = service.Save(t); Assert.IsInstanceOfType(data, typeof(AllographRequisition));
Assert.AreEqual(data.ApplicantDate, t.ApplicantDate);
}

  由于咱这的程序员节操无法保证,无奈之下,领域层中的聚合都被我用了internal的访问级别,保证即使他们引用了,也看的见摸不着,然后使用了友元的方式对特定的几个模块提供访问,抽象的模型所在模块的代码不对程序员公开,以此来保证封装好的逻辑不被胡乱引用而破坏。

[assembly: InternalsVisibleTo("ChanceVariation.Application.ApplicationService")]

  于是,拖了半天的剧情终于来到了正文部分,一般情况下用AutoMapper的时候都是映射public的属性,不过只要能访问的应该都是可以映射的,该怎么办呢,这几天google用域名访问不正常,懒得翻IP,只好先百度,不得不说百度对于中文分词是好些,可惜搜技术问题相当不给力,没发现一点有用的。于是只好去github上下AutoMapper的开源代码,由于我现在的系统只能装VS2012所以没办法连代码调试,只好一点点看,然后结合StackOverFlow上的一些讨论,终于找到了这个方法

        public IMappingExpression<TSource, TDestination> IgnoreAllPropertiesWithAnInaccessibleSetter()
{
var properties = typeof(TDestination).GetProperties().Where(HasAnInaccessibleSetter);
foreach (var property in properties)
ForMember(property.Name, opt => opt.Ignore());
return new MappingExpression<TSource, TDestination>(_typeMap, _serviceCtor, _configurationContainer);
}

此方法也可以解决private set不能映射的情况

internal DateTime ApplicantDate { get; private set; }

使用方法:

Mapper.CreateMap<AllographRequisitionData, AllographRequisition>()
.IgnoreAllPropertiesWithAnInaccessibleSetter()
.ForMember(dest => dest.ApplicantDate, opt => opt.MapFrom(source => source.ApplicantDate));

总算是映射成功了,不过终归是有些麻烦,暂时没时间管它了,这个月过去再琢磨有木有好办法。

AutoMapper对internal访问级别属性的映射的更多相关文章

  1. resultMap处理字段和属性的映射关系

    1.resultMap处理字段和属性的映射关系 若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射 <!-- resultMap:设置自定义映射 属性: id:表示自定 ...

  2. 001-List,数组,Set,Map属性的映射

    hibernate.cfg.xml: <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configur ...

  3. ASP.Net MVC 中EF实体的属性取消映射数据库、自定义名称

    例如:数据库中一个字段名称为CompanyId 自定义实体数据名称 [Column("CompanyId")] public int Id{ get; set; } 这样就可以使用 ...

  4. 关于ibatis的实体类部分属性无法映射

    今天在编码中不小心就遇到了一个ibatis初学者偶尔会遇到的问题. 先来看这张图中的DictionPo的部分属性赋值都为空.其实,数据库中是有数据的. 再来看看mapper的写法 上面那个对象查询语句 ...

  5. C#两个实体之间相同属性的映射

    public static R Mapping<R, T>(T model) { R result = Activator.CreateInstance<R>(); forea ...

  6. EF实体类指定部分属性不映射成数据库字段特性

    添加NotMapped 特性 /// <summary> /// 用户名 /// </summary> [NotMapped] public string user_name ...

  7. EF实体类指定部分属性不映射数据库标记

    命名空间 ;using System.ComponentModel.DataAnnotations.Schema; 实体部分 public partial class Student { [NotMa ...

  8. 使用AutoMapper进行对象间映射

    在开发过程中,难免遇到下面这种情况:两个(或多个)对象所拥有的大多数属性是重复的,我们需要在对象间进行映射(即将一个对象的属性值赋给另一个对象.通常我们可以进行如下操作: A a=new A(); a ...

  9. .NET的对象映射工具AutoMapper使用笔记

    AutoMapper是一个.NET的对象映射工具. 项目地址:https://github.com/AutoMapper/AutoMapper. 帮助文档:https://github.com/Aut ...

随机推荐

  1. nodejs模块发布及命令行程序开发

    前置技能 npm工具为nodejs提供了一个模块和管理程序模块依赖的机制,当我们希望把模块贡献出去给他人使用时,可以把我们的程序发布到npm提供的公共仓库中,为了方便模块的管理,npm规定要使用一个叫 ...

  2. 基于AOP的MVC拦截异常让代码更优美

    与asp.net 打交道很多年,如今天微软的优秀框架越来越多,其中微软在基于mvc的思想架构,也推出了自己的一套asp.net mvc 框架,如果你亲身体验过它,会情不自禁的说‘漂亮’.回过头来,‘漂 ...

  3. PHP 获取 特定时间范围 类

    目录  前序 用途 功能及事项 使用方法 代码及注释 前序: 总体来说,我更应该是一个 android 移动开发者,而不是一个 phper,如果说只做移动端的 APP ,我也不会学这么多,这 2年来, ...

  4. 在开启DRS的集群中修复VMware虚拟主机启动问题

    通过iSCSI方式连接到ESXi主机上的外挂存储意外失联了一段时间,导致部分虚拟主机在集群中呈现出孤立的状态,单独登陆到每台ESXi上可以看到这些虚拟主机都变成了unknow状态.因为有过上一次(VM ...

  5. [原]HAproxy 代理技术原理探究

    HAproxy 技术分享 简介 HAProxy是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件 Features 1.免费 2.能够做到4层以上代理 3.高性能 ...

  6. SignalR系列目录

    [置顶]用SignalR 2.0开发客服系统[系列1:实现群发通讯] [置顶]用SignalR 2.0开发客服系统[系列2:实现聊天室] [置顶]用SignalR 2.0开发客服系统[系列3:实现点对 ...

  7. [算法]——快速排序(Quick Sort)

    顾名思义,快速排序(quick sort)速度十分快,时间复杂度为O(nlogn).虽然从此角度讲,也有很多排序算法如归并排序.堆排序甚至希尔排序等,都能达到如此快速,但是快速排序使用更加广泛,以至于 ...

  8. RabbitMQ + PHP (二)AMQP拓展安装

    上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...

  9. 原生JS实现-星级评分系统

    今天我又写了个很酷的实例:星级评分系统(可自定义星星个数.显示信息) sufuStar.star();使用默认值5个星星,默认信息 var msg = [........]; sufuStar.sta ...

  10. arcgis api for js入门开发系列八聚合效果(含源代码)

    上一篇实现了demo的图层控制模块,本篇新增聚合效果,截图如下(源代码见文章底部): 聚合效果实现的思路如下: 1.map.html引用聚合包,项目已经包含进来了的聚合文件夹: <script ...