團隊開發(fā)框架實戰(zhàn)—Dto

1 為何需要DTO

為每個應用服務方法創(chuàng)建一個DTO起初可能被看作是一項乏味而又耗時的事情。但如果正確地使用它斧账,那么DTOs可能會拯救你應用出牧。為啥呢?

1.1 領域層抽象

DTO為展現層抽象領域對象提供了一種有效方式搏恤。這樣,層與層之間就正確分離了湃交。即使你想完全分離展現層熟空,仍然可以使用已存在的應用層和領域層。相反搞莺,只要領域服務的契約(方法簽名和DTOs)保持不變息罗,即使重寫領域層,完全改變數據庫模式才沧,實體和ORM框架迈喉,也不需要在展現層做任何改變绍刮。

1.2 數據隱藏

試想你有一個User實體,包含Id挨摸,Name孩革,EmailAddress和Password字段。如果UserAppService的GetAllUsers()方法返回一個List得运,即使你沒有在屏幕上顯示它膝蜈,那么任何人也都能看到所有user的密碼。它不是涉及安全的熔掺,而是與數據隱藏相關的饱搏。應用服務都應該返回給展現層需要的,不要更多置逻,也不很少推沸,要的是恰到好處。

1.3 序列化和懶加載問題

在一個真實應用中诽偷,實體之間是相互引用的坤学。User實體可能有一個Role的引用。因此报慕,如果你想序列化User,那么Role也會序列化压怠。而且眠冈,如果Role有一個List且Permission類有一個PermissionGroup類的引用等等。你能想象所有的對象都會被序列化的那種場景嗎菌瘫?你可能會意外地序列化整個數據庫蜗顽。那么解決方案是什么呢?把屬性標記為NonSerilized嗎?不雨让,你可能不知道它何時應該序列化雇盖,何時不應該。它可能在一個應用方法中需要栖忠,可能在另一個就不需要了崔挖。因此,在這種情景中庵寞,設計一個可安全序列化的狸相,特別設計的DTOs是一種好的選擇。

幾乎所有的ORM框架都支持懶加載捐川。它的特征是當需要時才從數據庫中加載實體脓鹃。假如說User類有一個Role類的引用。當從數據庫中獲得一個User時古沥,此時Role屬性還沒有填充瘸右,當第一次讀該Role屬性時娇跟,它才從數據庫中加載。因此太颤,不要將這樣的一個實體直接返回給展現層逞频,它可能會輕易造成從數據庫檢索額外的實體。如果序列化工具讀到了該實體栋齿,它會遞歸地讀取所有屬性苗胀,最終整個數據庫可能會被檢索(如果實體間有合適的關系)。

在展現層使用實體還會有更多的問題瓦堵。最好壓根不要在將包含領域(業(yè)務)層的程序集引用到展現層上基协。

2 DTO慣例和驗證

BatchDeleteInput

using System.Collections.Generic;

namespace Rdf.Application.Services.Dto
{
    public class BatchDeleteInput : IInputDto
    {
        public List<string> IdList { get; set; }
    }
}

JsonMessage

namespace Rdf.Application.Services.Dto
{
    public class JsonMessage : IOutputDto
    {
        public int ErrCode { get; set; }
        public string ErrMsg { get; set; }
        public object Result { get; set; }
    }
}

PageInput

namespace Rdf.Application.Services.Dto
{
    public class PageInput : IInputDto
    {
        public int PageIndex { get; set; }
        public int PageSize { get; set; }
        public string OrderBy { get; set; }
        public string Keyword { get; set; }
    }
}

PageOutput

using System.Collections;

namespace Rdf.Application.Services.Dto
{
    public class PageOutput : IOutputDto
    {
        public int Total { get; set; }
        public IEnumerable Records { get; set; }
    }
}

IDto

namespace Rdf.Application.Services.Dto
{
    /// <summary>
    /// This interface must be implemented by all DTO classes to identify them by convention.
    /// </summary>
    public interface IDto
    {
    }
}

IValidate

namespace Rdf.Application.Services.Dto
{
    /// <summary>
    /// This interface is implemented by classes those are needed to validate before use.
    /// </summary>
    public interface IValidate
    {
    }
}

IInputDto

namespace Rdf.Application.Services.Dto
{
    /// <summary>
    /// This interface is used to define DTOs those are used as input parameters.
    /// </summary>
    public interface IInputDto : IDto, IValidate
    {
    }
}

IOutputDto

namespace Rdf.Application.Services.Dto
{
    /// <summary>
    /// This interface is used to define DTOs those are used as output parameters.
    /// </summary>
    public interface IOutputDto : IDto
    {
    }
}

3 DTO和實體的自動映射

幸好,我們有工具可以讓這個變得很簡單菇用,AutoMapper就是之一澜驮。

Configuration.cs

using AutoMapper;

namespace Rdf.Web.AutoMapper
{
    public class Configuration 
    {
        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.AddProfile<Profiles.ActProfile>();
            });
        }
    }
}

ActProfile.cs

using AutoMapper;
using Rdf.Application.Act.Dtos;
using Rdf.Domain.Entities.Act;

namespace Rdf.Web.AutoMapper.Profiles
{
    public class ActProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<CreateRoleInput, Role>();
        }
    }
}

Startup.cs

// InitMapping
AutoMapper.Configuration.Configure();
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惋鸥,隨后出現的幾起案子杂穷,更是在濱河造成了極大的恐慌,老刑警劉巖卦绣,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耐量,死亡現場離奇詭異,居然都是意外死亡滤港,警方通過查閱死者的電腦和手機廊蜒,發(fā)現死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溅漾,“玉大人山叮,你說我怎么就攤上這事√砺模” “怎么了屁倔?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長暮胧。 經常有香客問我锐借,道長,這世上最難降的妖魔是什么叔壤? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任瞎饲,我火速辦了婚禮,結果婚禮上炼绘,老公的妹妹穿的比我還像新娘嗅战。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布驮捍。 她就那樣靜靜地躺著疟呐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪东且。 梳的紋絲不亂的頭發(fā)上启具,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音珊泳,去河邊找鬼鲁冯。 笑死,一個胖子當著我的面吹牛色查,可吹牛的內容都是我干的薯演。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼秧了,長吁一口氣:“原來是場噩夢啊……” “哼跨扮!你這毒婦竟也來了?” 一聲冷哼從身側響起验毡,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤衡创,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后晶通,有當地人在樹林里發(fā)現了一具尸體璃氢,經...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年录择,在試婚紗的時候發(fā)現自己被綠了拔莱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡隘竭,死狀恐怖,靈堂內的尸體忽然破棺而出讼渊,到底是詐尸還是另有隱情动看,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布爪幻,位于F島的核電站菱皆,受9級特大地震影響,放射性物質發(fā)生泄漏挨稿。R本人自食惡果不足惜仇轻,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望奶甘。 院中可真熱鬧篷店,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹄殃,卻和暖如春携茂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诅岩。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工讳苦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吩谦。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓鸳谜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逮京。 傳聞我的和親對象是個殘疾皇子卿堂,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內容