
3人ã®ããã°ã©ããŒããã£ãŒã«ããæšªæããå察åŽã®å®¶ã«çãããã«é ŒãŸããŸããã åå¿è
ããã°ã©ããŒã¯çãè·é¢ãèŠãŠããããã¯ããé ããªãïŒ 10åããããŸããã çµéšè±å¯ãªããã°ã©ããŒããã®åéãèŠãŠããã°ããèããŠãã1æ¥ã§ããã«çãããšãã§ããããšèšã£ãã æ°äººã¯é©ããŠåœŒãèŠãã ãœãããŠã§ã¢ã®ç¬¬äžäººè
ã¯ãã®åéãèŠãŠèšã£ãã ã10åã»ã©ã§ããã15åã§ååã ãšæããŸããã çµéšè±å¯ãªããã°ã©ããç¬ã£ãã
åå¿è
ããã°ã©ããŒã¯åºçºããŸããããæ°å以å
ã«å°é·ãççºãå§ãã倧ããªããããæ®ããŸããã ççºãããåœŒã¯æ»ã£ãŠé£ãã ããããŠåœŒã¯æåããããçŽããªããã°ãªããªãã£ãã ç®æšãéæããã®ã«2æ¥ããããŸããã ããã«ã圌ã¯è³ãæã§æºããå°çãããšãã«è² å·ããŸããã
çµéšè±å¯ãªããã°ã©ããŒãåã€ãcããããŸããã å°é¢ãåªããææ¢ãããé±å±±ãæ¢ããŠãå®å
šã ãšç¢ºä¿¡ããå Žåã«ã®ã¿ç§»åããŸããã ãã£ãããšæ³šææ·±ãåœŒã¯æ¥äžã«çãæž¡ã£ãã æ°åãã£ãã ãã§ãã
ããã°ã©ããŒã®ç¬¬äžäººè
ã¯åºçºãããã£ãŒã«ãããŸã£ããã«è¡ããŸããã æå³çãã€çŽæ¥çã 圌ã¯ããã10åã§ç®æšãéæããŸããã
ããããã©ã®ããã«ç®¡çããŸãããïŒãä»ã®2人ã«å°ããŸããããã©ããã£ãŠåäžã®é±å±±ãåŒã£æããªãããã«ããã®ã§ããïŒã
ãç°¡åããšåœŒã¯çããã ãç§ã®éã«å°é·ãæ·ããŸããã§ãããã
æ®å¿µãªãããç§ã¯èªããããåŸãŸãã-ç§ãã¡ã¯èªåã®å°é·ãæ·èšããŠããŸãã
æåã®éšåã§ã¯ããœãããŠã§ã¢éçºã®äž»ãªãªã¹ã¯ã詳现ã«èª¿ã¹ããããã®ãªã¹ã¯ã軜æžããæè¡çããã³æ¹æ³è«çãªæ¹æ³ã«ã€ããŠèª¬æããŸããã éå»1幎éãç§ã¯å€ãã®ã³ã¡ã³ããåãåããŸããããã®äž»ãªæå³ã¯æ¬¡ã®ãšããã§ããïŒããã¹ãŠãã¯ãŒã«ã§ãããã©ãããå§ããŠãå®éã®äžçã§ã©ã®ããã«èŠããããã å®éãæåã®ããã¹ãã¯ããçè«çãªæ§è³ªã®ãã®ã§ããããªã³ã¯ã®ã«ã¿ãã°ã衚ããŠããŸãã ãã®èšäºã§ã¯ãã§ããã ãå€ãã®äŸã瀺ããŸãã
ååãªçµéšããªãããã°ã©ããŒã®å Žåã
æåã®èšäºã§èª¬æããåé¡ã®å€ãã¯ãé·ãç®ã§èŠãã ãã§çè§£ã§ããªãå¯èœæ§ããããŸãã10ããŒãžã«ãµã€ããèšè¿°ããæ¹æ³ãšããã£ã«ã¿ãªã³ã°çšã®ããã€ãã®ãã©ãŒã ãšCRUD管çããã«ã«å€§ããªéãã¯ãããŸãããã¹ãŠã®ã³ãŒãã¯æ°æ¥ã§ãŒãããæžãçŽãããšãã§ããŸãã ãããã1幎åã2幎ã§äœãèµ·ããã§ããããïŒ
ç§ãã¡ã®ãµã€ãã¯éçºãéå§ããæ°ããæ©èœãç»å Žãããã§ã«æ°åã®ããŒãžãšãã©ãŒã ããããå€éšãªãœãŒã¹ãšã®ã¢ãã£ãªãšã€ãããã°ã©ã ã远å ãããŠããŸãã 倧å¯è±ªãVkontakteãã«åºåãåºããããŒãäžã«ã¡ã€ã³ããŒãžããéçºãããŸããã é¢ä¿ãããŸããããã£ãã·ã¥ã«ãšã©ãŸããŸãã ä»ãããªãã¯ããã«ãã¬ã³ããªãŒãªãµãŒãã¹ãšææºããå¿
èŠããããŸãã ã³ãŒãããŒã¹ããããŒãããŒãšçµ±åã³ãŒããã³ããŒããŠè²Œãä»ãããç§ãã¡ã®ãããŒã¿ãšãå€éšã®ãããŒã¿ãåæããããã®ãã¡ã€ã«ãäœæããŸãã
倿Žã¯ããžãã¹ã«ãŒã«ã§å§ãŸããã¹ãã¬ãŒãžã®ã³ãŒããšãµããžã§ã¯ããšãªã¢ã§è€è£œããå¿
èŠããããã¡ã€ã³ããŒãžã®ãã£ãã·ã¥ã宿çã«æŽæ°ããå¿
èŠããããããã¯ãã°ã®ãã°ãšæ§æã®åé¡ã®æ°ãå¢ããŠããŸãã
ããžãã¹ã«ãŒã«ã®å€æŽãçµ±åãããã©ãŒãã³ã¹ã®æé©åãæ©èœã®æ¡åŒµã6ã7åç¹°ãè¿ããã¹ã¿ãã¯ãªãŒããŒãããŒãããŒãããŒã®SDKã³ãŒããæŸèæããããããããããŸããŸãªéåžžã«åœ¹ç«ã€ãµãŒãããŒãã£ã®ã³ã³ããŒãã³ããããã³ç¬èªã®èªè»¢è»ãããªããµã³ãã«ã³ãŒããããã©ã³ã±ã³ã·ã¥ã¿ã€ã³ã¢ã³ã¹ã¿ãŒãäœæããŸããã
2-3幎åã®ã³ãŒãã§ä¿®æ£ããªããã°ãªããªãäž»ãªåé¡
- å®åã³ãŒãã®ç¹°ãè¿ãïŒäœ¿çšãtry-catchãlogãªã©ïŒïŒã³ãŒãããŒã¹ã®å€æŽãä¿®æ£ãå°é£ã«ãªããåãæ§æãæžãã®ã«éãã«æéãããããŸãïŒãããžã§ã¯ãã®æåã®æ°ç§ã1幎ãŸãã¯2æ¥åŸïŒã³ãŒãããŒã¹ã®ååšïŒ
- åãEntityãDTOãããã³ViewModelã¯ã©ã¹ã®æé»çã§æãããã®ãªãäœæãLinqã¯ãšãªã®è€è£œãåãã¿ã€ãã®ITEntityRepositoryã®äœæãå«ãã³ãŒãã®éè€ïŒå®è£
ã1ã€ãããªãIRepository <TEntity>ã€ã³ã¿ãŒãã§ã€ã¹
- SRPã®éåïŒç°ãªãã³ã³ããã¹ãããã®ãšã³ãã£ãã£ããããã£ã®è©°ã蟌ã¿ããã¡ã€ã³ã¢ãã«ãšã¯é¢ä¿ãªããããŸããŸãªãããŒãžã£ãŒããµãŒãã¹ããã«ããŒãæç¢ºãªè²¬ä»»ã§äœæãã
- LSPéå
- NullReferenceException
- ããŒã¿ãšã©ãŒ
- ãã£ãŒãããã¯ã®äœæãã¢ããªã±ãŒã·ã§ã³ã¬ã€ã€ãŒãã€ã³ãã©ã¹ãã©ã¯ãã£ã³ãŒãããã¡ã€ã³ã¢ãã«ã³ãŒãã®æ··å
éåžžããã®ãã¹ãŠã®æãã®æ£åœåã¯æ¬¡ã®ãšããã§ãã- ã¿ã€ããªãªãªãŒã¹æ¥
- ãªãã¡ã¯ã¿ãªã³ã°ããæéããªã
- èšç»ãšèšèšã®æéäžè¶³ïŒã©ã®ã¢ãŒããã¯ãã£ã§ããïŒ
äžè¬ã«ãããã¯ãã¹ãŠçå®ã§ãããçµéšè±å¯ãªéçºè
ã§ãããé©åãªæ±ºå®ãè¿
éã«äžãã®ã«ååãªããããéšåãããªãããšãå€ãããšãèªããªããã°ãªããŸããã ãæ¬åœããšããããšã§ãç§ã¯æ¬¡ã®ç¶æ³ãçè§£ããŠããŸãïŒ80ïŒ
ã®å Žåãããžãã¹ã±ãŒã¹ãå®è¡ããã³ãŒããèšè¿°ãã20ïŒ
ã®å Žåãç¹å®ã®20ïŒ
ãèšè¿°ããå¿
èŠãããïŒã€ãŸããèŠä»¶ãã©ã®ããã«å€åãããïŒãæšæž¬ãããã³ã«ãå°ãå
ãè¡ã£ãŠããŸãã å©å®³é¢ä¿è
ãæããã®ïŒã¢ããªã±ãŒã·ã§ã³ã®ãã¡ã€ã³ã¢ãã«ãã©ã®ããã«å€åãããïŒãæšæž¬ããã«ã¯ãéåžžã管çäœæ¥ã®çµéšããã³/ãŸãã¯ãµããžã§ã¯ããšãªã¢ã®çµéšãå¿
èŠã§ãã
ãã ããå€ãã®æé·äžã®ãããžã§ã¯ãã§çºçããå€ãã®èŠä»¶ããããŸãã- ãã«ããŠãŒã¶ãŒã¢ã¯ã»ã¹ïŒæªåé«ãhabr广ïŒããã¥ãŒããããïŒãªã©ã®ã«ãŠã³ã
- åæãšããŒãœãã©ã€ãŒãŒã·ã§ã³ïŒè²©å£²ãã¡ãã«ã®æ§ç¯ãããé¢é£æ§ã®é«ãã³ã³ãã³ããæäŸããããã®ãŠãŒã¶ãŒèšå®ã®åæïŒ
- å
šææ€çŽ¢
- ã¹ã±ãžã¥ãŒã«ãããã¿ã¹ã¯ãšã¹ã±ãžã¥ãŒã«ãããã¿ã¹ã¯
- ããŒã¿ã®ãã£ã«ã¿ãªã³ã°ã倿ãããã³ããŒãžã³ã°
- ãã®ã³ã°ãéç¥ã·ã¹ãã ãç£èŠãèªå·±èšºæãé害ããã³ãšã©ãŒåŠçåŸã®èªå·±å埩
ãã®èšäºã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã€ã³ãã©ã¹ãã©ã¯ãã£ãããã¡ã€ã³ïŒããžãã¹ã«ãŒã«ïŒãåé¢ããããšã«çŠç¹ãåœãŠãŸãã ãã¹ãŠã®AOPãåçã³ã³ãã€ã«ãããã³ãã®ä»ã®éæ³ã¯æ¬¡åã«æ®ãããŸãã
10ã®ã¢ããªã±ãŒã·ã§ã³å±€ã§ãã¹ãŠã®äººã«ååãªã¯ãã§ã

ãç空äžã®éåžžã®Webã¢ããªã±ãŒã·ã§ã³ãã®å Žåãæå€§10å±€ãã«ãŠã³ãããŸããã ããã¯ããããã§ããããããšãå°ãã§ããïŒ ãã³ãŒããŒãã«ãããããŠå€å
žçãª3ã€ã§ããŸãããããšãã§ãããšããã°ãããã¯ã¡ããã©ãããšæããŸãã ãšã³ããã€ã³ããããŒã¿ããããŒããããªãã·ã£ãŒãµãã¹ã¯ã©ã€ããŒãã€ã³ãã¬ã»ãã¿ãŒãæšå¥šããŸãã æ®ãïŒ
- ãµãŒãã¹
- ã³ãã³ã/ã¯ãšãª
- ãšã³ãã£ãã£
- DAO
ãã¹ãŠãé©åãªå Žæã«é
眮ããããã«ãWebã¢ããªã±ãŒã·ã§ã³ã®æãåçŽãªã±ãŒã¹ã§ããã©ã³ãã£ã³ã°ããŒãžããå§ããŸãããã
ã©ã³ãã£ã³ã°ããŒãžïŒããšãã°ããã©ã³ãã£ã³ã°ããŒãžãïŒ-ç¹å®ã®æ¹æ³ã§æ§ç¯ãããWebããŒãžããã®äž»ãªã¿ã¹ã¯ã¯ã察象ãŠãŒã¶ãŒã®é£çµ¡å
æ
å ±ãåéããããšã§ãã åºåã®å¹æãé«ããèŠèŽè
ãå¢ããããã«äœ¿çšãããŸã...
1ããŒãžãããããªãŒãããåéããŸãã ãªãŒãã«ã¯ã¡ãŒã«ãå¿
èŠã§ãã ãã©ãŒã ã®ãªãã·ã§ã³ã®ãã£ãŒã«ãã¯ãé»è©±çªå·ãšååã§ãã ã¯ã©ã¹ãleadããäœæããŸãããïŒ
public interface IEntity { string GetId(); } public class Lead : IEntity { public static Expression<Func<Lead, bool>> ProcessedRule = x => x.Processed; private string _email; [Key, Required, Index("IX_Email", 1, IsUnique = true)] public string Email { get { return _email; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("email"); } _email = value; } } public string Phone { get; set; } public bool Processed { get; set; } public DateTime CreatedDate { get; set; } [Obsolete("Only for model binders and EF, don't use it in your code", true)] internal Lead() { } public Lead([NotNull] string email, string phone = null) { Email = email; Phone = phone; CreatedDate = DateTime.Now; } public bool IsProcessed() { return this.Is(ProcessedRule); } public string GetId() { return Email; } }
ãšã³ãã£ãã£ããªãããã¡ã€ã³ã¢ãã«ãããã³é²åŸ¡ããã°ã©ãã³ã°ïŒå¥åã«ãã»ã«åïŒ
è«äºïŒ
samolisov.blogspot.ru/2012/10/anemic-domain-model.htmlç§ã¯ãªãããã¡ã€ã³ã¢ãã«ïŒãªãããã¡ã€ã³ã¢ãã«ïŒã®æ¯æè
ã§ãããè²§è¡ã奜ãã§ã¯ãªããããLeadã¯é©åãªã³ã³ã¹ãã©ã¯ã¿ãŒãæã¡ãççŸããç¶æ
ïŒäžå€æ¡ä»¶ã«éåïŒã«é¥ãããšãèš±å¯ããŸããã ç¥å
ãè²§è¡ã¢ãã«ãçã¿åºããçŸä»£ã®ORMãã¬ãŒã ã¯ãŒã¯ã«ãããã«ãã»ã«åã®åçã芳å¯ããããšãã§ããŸãïŒã»ãšãã©ïŒã å
éšã¢ã¯ã»ã¹ä¿®é£Ÿåã圹ç«ã¡ãŸãã ç¹ã«ãæãæŽãããããã©ã«ãã§ã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããªããŠãŒã¶ãŒã«ã¯ããã¡ã€ã³ã¢ã»ã³ããªå
ã«[Obsolete]屿§ããããŸãã 2çªç®ã®ãã©ã¡ãŒã¿ãŒã¯ããã®ã³ã³ã¹ãã©ã¯ã¿ãŒãæç€ºçã«äœ¿çšããããšãããšãã«ããäžæããŸãããORMãšModelBinderã¯ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒãå·éã«äœ¿çšããŸãã
[Obsolete("Only for model binders and EF, don't use it in your code", true)] internal Lead() { } public Lead([NotNull] string email, string phone = null) { Email = email; Phone = phone; CreatedDate = DateTime.Now; }
ãžã¥ãã¢ããããåé€ããªããšããä¿èšŒã¯ãããŸãããããã®ãããªããšã¯ã³ãŒãã¬ãã¥ãŒäžã«è§£æ±ºã§ããŸãã
.NETã®ããããã£ã¯ãããŒã¿ããŒã¹ã«ãããããããã ãã§ãªããçºæãããŸããã ãã®ãããªã³ãŒãã®ç·šæã«ãããããŒã¿ããŒã¹ã«ä¿åãããšãã§ã¯ãªããééã£ãé»åã¡ãŒã«ãèšå®ããããšããå Žæã«æ£ç¢ºã«åãŸããŸããããã¯ãå€ãèšå®ãããç¬éãããç¹ã«å€§èŠæš¡ãªæäœäžã«éåžžã«é ãããšããããŸãã
[Key, Required, Index("IX_Email", 1, IsUnique = true)] public string Email { get { return _email; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("email"); } _email = value; } }
ã³ã³ã¹ãã©ã¯ã¿ãŒã¯Emailããããã£ã䜿çšãããããäžå€åŒã¯ç¢ºå®ã«ä¿è·ãããŸãã
ãã®æ¹æ³ã§äœæ¥ããæ¹ãç°¡åãªã®ã§ãã«ãŒã«-ã³ãŒããã¡ãŒã¹ãã ãŸãããã¡ã€ã³ã¢ãã«ãäœæããæ¬¡ã«èªåç§»è¡ãäœæãïŒãããã£ãŠãEntity Frameworkã䜿çšïŒãå®è¡ããŸãã
ç§ã®èгç¹ãããããšããã©ã¡ãŒã¿ãŒã®ãªãã³ã³ã¹ãã©ã¯ã¿ãŒãžã®ã¢ã¯ã»ã¹ãpublicïŒpublicïŒã«çœ®ãæããŠãåãã¿ã€ãã®äžèŠãªDTOãšViewModelãäœæããã«ãã®ããã«èšè¿°ããããšã¯æ¥ãã¹ãããšã§ã¯ãããŸããã
[HttpPost] public ActionResult Index(Lead lead) { if (!ModelState.IsValid) { return View(lead); }
æ¡ä»¶ã®äžã§ïŒ
- ãªãŒãã¯ã©ã¹ã¯éçŽã®ã«ãŒãã§ã¯ãããŸãã
- ã¢ããªã±ãŒã·ã§ã³ãã©ãŒã ã«ã¯ããªãŒãã¯ã©ã¹ãš1察1ã®ãããã³ã°ããããŸãã
- ãã©ã¡ãŒã¿ãŒãªãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãObsolete屿§ã«ãã£ãŠä¿è·ãããŠããŸã
ãã以å€ã®å Žåã¯ãDTOããã³/ãŸãã¯ViewModelãäœæããDataMapperã䜿çšããŸãã
Visual Studio 2015ãCTPã«æ°ããæŒç®åãæ®ãéãããã®ã¢ããã¯ã³ãŒããèªã¿ãããããã®ã«åœ¹ç«ã¡ãŸãã RïŒã®ãšã©ãŒãšããŠãJetBrains.Annotationsããã³NullReferenceExceptionã®å¯èœæ§ãšçµã¿åãããŠMaybeã䜿çšãããšãã³ãŒãã«NullReferenceExceptionãååšããªãããšãä¿èšŒãããŸãã å®éãããã¯NullObjectãã¿ãŒã³ã®æ©èœçãªã¹ã¿ã€ã«ã®å®è£
ã§ãã
ããžãã¹ããžãã¯ãšã€ã³ãã©ã¹ãã©ã¯ãã£ïŒDDDïŒã®åé¢
DDDããããäž»ãªè«äºã¯ã次ã®ç¹ãäžå¿ã«å±éãããŸãã
- ãããã¯ãŒã¯äžã®DDDã§å
¬éãããŠããã¢ã¯ã»ã¹å¯èœãªäŸãå°ãªãããããããããäœã§ãããã¯æç¢ºã§ã¯ãããŸãã
- ãã¡ã€ã³ãšèŠãªããããã®ãšã€ã³ãã©ã¹ãã©ã¯ãã£ãšã¯äœã§ãã
- DDD-op-opãready codeæ¹æ³è«ãšæ¯èŒããŠéåžžã«é·ãé«äŸ¡ã§ã
Evansã®æ¬ãèªãããšã¯ã
The Art of Unit Testingã«ç¶ããŠãã³ãŒããçè§£ããäžã§ç§ã«ãšã£ãŠ2çªç®ã®
æ¥è»¢ã§ããã ãœãããŠã§ã¢éçºã®10幎éãç§ã¯ååãªæ°ã®ã³ãŒãããŒã¹ãååã«åŸãããšãã§ããŸããã ãããããããšã«ããã¹ãŠã®ããã°ã©ãã³ã°èšèªã«ã¯ãã§ã«åºæ¬çãªãã©ãããã©ãŒã ïŒãã¬ãŒã ã¯ãŒã¯ïŒãšããã±ãŒãžãããŒãžã£ãŒãããããã©ãã¯ãžã£ãã¯ãšé女ã§MVCãã¬ãŒã ã¯ãŒã¯ãèšè¿°ããããšã¯èª°ã«ãèµ·ãããŸããã
ãã ããããžãã¹ããžãã¯ã¯ãã¢ããªã±ãŒã·ã§ã³å
ã®ããŸããŸãªå ŽæïŒã¹ãã¢ãããã·ãŒãžã£ããã«ããŒããããŒãžã£ãŒããµãŒãã¹ãã³ã³ãããŒã©ãŒæ¬äœããªããžããªãlinqã¯ãšãªïŒã§èŠã€ããããšãã§ããŸãã æç¢ºãªèŠå¶ããªãå Žåãåéçºè
ã¯ãçŸãããã®ã«ã€ããŠã®ã¢ã€ãã¢ã«åŸã£ãŠããžãã¹ããžãã¯ãç·šæããŸãã
ããã¯åé¡ã®å
šäœãäœæããŸãïŒ- ããžãã¹ã«ãŒã«ãæ¢ãå Žæãæç¢ºã§ã¯ãªã
- ãã¡ã€ã³ã¢ãã«ã³ãŒãã®ãã¹ãã«ãã¬ããžãšã¯äœããšãã質åã«æç¢ºã«çããããšã¯äžå¯èœã§ãã
- ã³ãŒãã¯æç¶ãåã¹ã¿ã€ã«ã«åŒãå¯ããããã«ãã»ã«åã¯å£ããŠããŸã
- 2ãæä»¥äžã§ããžãã¹ã«ãŒã«ãè€è£œããå±éºããããŸãïŒããšãã°ãcïŒã³ãŒããšã¹ãã¢ãããã·ãŒãžã£ã³ãŒããèŠä»¶ã倿Žãããå Žåã1ãæã®ã¿ã§ã«ãŒã«ã倿Žãããå¯èœæ§ããããŸãããã®çµæãå·®ç°ã¯æ®ããæ°ãæåŸã«çºçããå¯èœæ§ããããŸããä»ã®äººã¯åé¡ã«ãªããŸããããããã©ã®ããã«ãæ£ããããã¹ããããç¥ã£ãŠãããšããäºå®ã§ã¯ãããŸãããããã«ããããŒãžã£ãŒãšãã«ããŒã¯äžæç¢ºãªè²¬ä»»ãæã€ã¯ã©ã¹ã§ãããé«ã確çã§æéãšãšãã«ç¥ã®ãªããžã§ã¯ãã«å€ãããŸã
- ã¢ã»ã³ããªéã®äŸåé¢ä¿ã¯äžåèŠå¶ãããŠããŸããã ãžã¥ãã¢ã®è»œéãã¡ã€ã³ã¢ãã«ã¯ã©ã¹ã¯ãWebã³ã³ããã¹ããšCommon.Webã®ã¢ã»ã³ããªã«ç°¡åã«äŸåãå§ããããšãã§ããŸãã
ããé«ãã¬ãã«ã§ã¯ãããã¯æ¬¡ã®ããã«å€æãããŸãã- ãã«ã¿ã€ã ããŒã å
šäœããã°ã®ãµããŒããšãã°ã®é€å»ã«å¿ããç¶æ
ãŸã§ãéçºã®ããŒã¹ãé
ããã
- çµ¶ãéãªããã°ä¿®æ£ãšæŸèæ
- ã¢ããªã±ãŒã·ã§ã³ããŒã¿ããŒã¹ã®ãšã©ãŒããµããŒãããã³æé€ããããã«è¿œå ã®ãªãœãŒã¹ãå²ãåœãŠãå¿
èŠããã
ç§ã«ãšã£ãŠãEvans DDDã¯ããžãã¹ããžãã¯ã§äœæ¥ãæšæºåããæ¹æ³ã§ãã DDDã¯ããã®ããã®äžé£ã®ãã¿ãŒã³ãæäŸããŸãã äž»ãªãã®ãèŠãŠã¿ãŸãããã åæã«ãå¥ã®ããã¡ãã·ã§ããã«ãªãã³ã³ã»ããã§ãããCQRSããšãçµå©ãããŸãã
ããã¯DDDãšã©ã®ããã«é¢é£ããŠããŸããïŒ
DDDã¯ããã¡ã€ã³ãå¥åã§ãããã€ã³ãã©ã¹ãã©ã¯ãã£ãå¥åã§ããããšã瀺ããŠããŸãã ããŠãããšã³ãã£ãã£ãããããŸãã
ãšã³ãã£ãã£
public interface IEntity { string GetId(); }
ãšã³ãã£ãã£ã¯ãäžæã®èå¥åãæã€ãã®ã§ãã è¢ã®äžã®2æ¬ã®éã¯ãšã³ãã£ãã£ã§ã¯ãããŸããããªããªããããªãã¯äžæ¹ã仿¹ãšåºå¥ã§ããªãããã§ãã ãã¡ã€ã³ã«é¢ããŠã¯ããããã¯åäžã§ãã ããããç§ãã¡ã®çšã®ããã®VasyaãšPetya-ãšã³ãã£ãã£ã çŽçšè
çªå·ïŒTINïŒããããŸãã
ææ°ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãæãäžè¬çã«äœ¿çšãããIDã¯èªåã€ã³ã¯ãªã¡ã³ãæŽæ°å€ãŸãã¯GUIDã§ãã ãã®ã¢ãããŒãã®æ®åã«ãããããããå Žåã«ãã£ãŠã¯ãç¹å¥ãªåŠçãå¿
èŠãšããç¶æ³ãäœãåºãããšãã§ããŸãã èªç©ºäŒç€Ÿã®ãã±ãããã¢ã°ãªã²ãŒã¿ãŒãã賌å
¥ããããšãããå Žåãã¢ã°ãªã²ãŒã¿ãŒã®äºçŽçªå·ã¯èªç©ºäŒç€Ÿã®äºçŽçªå·ãšäžèŽããªãããšããããŸãã ããã¯ããã£ãªã¢ãç¬èªã®ITã·ã¹ãã ãæã¡ãã¢ã°ãªã²ãŒã¿ãŒãç¬èªã®ã·ã¹ãã ãæã£ãŠãããšããäºå®ã«ãããã®ã§ãã
ã©ã³ãã£ã³ã°ããŒãžã«æ»ã£ãŠããµã³ãã«ããªãŒãããŸãããã IEntityã®æãæœè±¡çãªå®è£
ã¯ãIDãæååãšããŠè¿ãã¡ãœããã§ãã ç§ã¯æå³çã«ããããã£ã§ã¯ãªãã¡ãœããã䜿çšããŸãã Leadã¯ã©ã¹ã®ãã¹ãŠã®ããããã£ã¯ãããŒã¿ããŒã¹ãã£ãŒã«ãã«ããããããŸãã ããã«ããããããŸãããé¿ãããããã³ã°ãèŠãå¿
èŠããªããªããŸãã äž»ããŒã¯ãIDã§ã¯ãªãé»åã¡ãŒã«ã§ãã Idããããã£ãå®è£
ããå ŽåãIdããããã£ãããŒã¿ããŒã¹ã®Emailãã£ãŒã«ãã«ããããããŠããããšãæç€ºçã«ç€ºãå¿
èŠããããŸããããã«ãããã«ããä»ã®ã¿ã€ãïŒæŽæ°ãšGUIDïŒã®äž»ããŒã«åé¡ãçºçããŸã
public class Lead : IEntity { private string _email; [Key, Required, Index("IX_Email", 1, IsUnique = true)] public string Email { get { return _email; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("value"); } _email = value; } } public string Phone { get; set; } public bool Processed { get; set; } public DateTime CreatedDate { get; set; }
ORM Entity Frameworkãã¡ã€ã³ãšããŠäœ¿çšããããšã¯æ¢ã«è¿°ã¹ãŸããããããã ãã§ã¯ãããŸããã äž»ãªçç±ïŒ
- ç§»è¡ã®èªåçæïŒå€ãã®æéãç¯çŽããã«ãŒãã³ã³ãŒããèšè¿°ããå¿
èŠããããŸããïŒ
- .NETã§ã®æé«ã®linqãµããŒã
- NHibernateããéãéçº
- ããŒã¿ã®ãããã³ã°ãšç§»è¡ã®äœæã®ããã®DataAnnotation屿§ããµããŒã
æµentãªãããã³ã°VS Atributeãããã³ã°
ãã¡ããããã¹ãŠã®ããŒã«ãŒã®å³ãšè²ã¯ç°ãªããŸãã æµmappingãªãããã³ã°ã¯ããã¯ãªãŒã³ã§ããããã¡ã€ã³ã¢ã»ã³ããªã«å¿ããŠEFããã©ãã°ããããšã¯ã§ããŸãããããã®åé·æ§ãš2ã€ã®ã¯ã©ã¹ããµããŒãããå¿
èŠæ§ã奜ãã§ã¯ãããŸããïŒãšã³ãã£ãã£ãšãããã³ã°ã ããã¯SRPéåã§ãããšèª°ããèšããããããŸããã ç§ã®æèŠã§ã¯ã屿§ã¯å¿
é ã®ã³ãŒãã§ã¯ãªãããã®ãããªæ¯èŒã¯æ£ãããããŸããã èšé²ã®åœ¢åŒãšEFãžã®äœåãªäŸåã ãã«éããèŠãããŸãããå¿
èŠã«å¿ããŠç°¡åã«åãåãããšãã§ããŸãã
æ°žç¶æ§ã®ç¡ç¥
ãã®ããããã¡ã€ã³ãšã³ãã£ãã£ããããããŒã¿ãœãŒã¹ããããŒã¿ãäœæãåŠçãä¿åããã£ã«ã¿ãªã³ã°ãååŸãåé€ããå¿
èŠããããŸãã äžè¬ã®äººã
ã§ã¯ãããã¯CRUDæäœãšåŒã°ããŸãã ãªããžã§ã¯ãã®äžå€åŒã«éåããªããæ£ãããã³ã³ã¹ãã©ã¯ã¿ã䜿çšããå¿
èŠãããããšãå¿ããã«ãnewæŒç®åã䜿çšããŠãšã³ãã£ãã£ãäœæã§ããŸãã ORMãµããŒãã®ããã«ã®ã¿ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã宣èšãã[Obsolete]屿§ã䜿çšããŠæ±ããæããèªåèªèº«ãä¿è·ããŸããã
ãªããžã§ã¯ããä¿åããŠããŒã¿ãœãŒã¹ããååŸããã«ã¯ã©ãããã°ããã§ããïŒ ææ°ã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãã¢ã¯ãã£ãã¬ã³ãŒãïŒARïŒãšäœæ¥åäœïŒUoWïŒã®2ã€ã®ã¢ãããŒãã䜿çšãããŸãã ç§ã¯Active Recordã®åŒ·æµã§ãã è§£éãããPLã§ã¯ARãå©ç¹ãäžããå¯èœæ§ããããŸãããã³ã³ãã€ã«ãããPLã§ã¯ããã§ã¯ãããŸããã ARã¯æãRPãæ¹æ³ã§SRPã«éåããSaveã¡ãœããããã¹ãŠã®ãšã³ãã£ãã£ã«è¿œå ããŸãã ãšã³ãã£ãã£ã®ã¿ã¹ã¯ã¯ãããŒã¿ããŒã¹ã«èªèº«ãä¿åããã®ã§ã¯ãªããããžãã¹ããžãã¯ãå®è£
ããããŒã¿ãã«ãã»ã«åããããšã§ãã ãããã£ãŠãç§ã®éžæã¯ãããã§ãã
public interface IUnitOfWork: IDisposable { void Commit(); void Save<TEntity>(TEntity entity) where TEntity : class, IEntity; void Delete<TEntity>(TEntity entity) where TEntity : class, IEntity; }
EFã®å ŽåãUoWå®è£
ã¯ã¢ããªã±ãŒã·ã§ã³ã®DataContextã«ãªããŸãã ãã ããDataContextèªäœã¯ãã¡ã€ã³ã¢ã»ã³ããªã«åºå·ããŸããã ãŸãããªãããã§EFã«äŸåããå¿
èŠãããã®ã§ããïŒ æ¬¡ã«ãå€ãã®å ŽåãéçºããŒã ãåé¢ããããã«å¢çã³ã³ããã¹ããå®è£
ããå¿
èŠããããŸãããããŒã¿åç·ã®åæè§£é€ã®ãªãã·ã§ã³ãé€å€ããã«ã¯ãåãDataContextå
ã«ç§»è¡ãæ®ãæ¹ãè¯ãã§ãã
ä¿åãç·šéãåé€ã®æ¹æ³ã¯æç¢ºã§ãã ããŒã¿ãååŸããæ©èœã¯æ®ããŸãã åŸæ¥ããã®æ©èœã¯ãªããžããªã䜿çšããŠå®è£
ãããŠããŸããã ãããŠäŒçµ±çã«ãäžåšçšã«ãå®è£
ãããŸããã åé¡ã«ã€ããŠã¯ãã
åé¡ã®ãããªããžããªãã³ãã¬ãŒã ãã®èšäºã§è©³ãã説æããŠã
ãŸã ã
èŠããã«ãæåã«ãããè¡ããŸãïŒ public interface IRepository<T> { T GetById(int id); IEnumerable<T> GetAll(); bool Add(T entity); bool Remove(T entity); }
çµæã¯æ¬¡ã®ãšããã§ãã
class AccountRepository : IRepository<Account> { public Account GetByName(string name); public Account GetByEmail(string email); public Account GetByAge(int age); public Account GetByNameAndEmail(string name, string email); public Account GetByNameOrEmail(string name, string email);
ãã®ãããªç¶æ³ãçµäºããŸãïŒä»¥äžã«èª¬æããçç±ã«ãããæ¡åŒµã¡ãœããã䜿çšãããªãã·ã§ã³ã¯èæ
®ããŸããïŒã
public interface IRepository<T> { T GetById(int id);
ãã ããæ¬¡ã®ããã«äžæããŸãã
æåŸã®äŸã§ã¯ãæåã®2ã€ã®linqã¯ãšãªã¯ãã¢ã¯ãã£ãã¢ã«ãŠã³ãããžãã¹ã«ãŒã«ã®å€æŽã瀺ããŠããŸãã æåã¯ãåé€ãããŠããªããã®ãã¢ã¯ãã£ãã§ãããšèŠãªããããã©ã³ã¹ã¯ãŒããã倧ãããªããã°ãªããªãããšããèŠä»¶ã远å ãããŸããã linqã¯ãšãªã¯éåžžã«ç°¡åã«èšè¿°ã§ãããããã³ãŒãããŒã¹ã®æ°åç®æã«ã³ããŒãããŸãã ã»ãšãã©ç¢ºå®ã«ã©ããã§ããã倿ŽããŸãããã©ããã§ãããå¿ããŸãã
3çªç®ã®äŸã¯æ£åžžã«ã³ã³ãã€ã«ãããŸãããORMã¯getCurrentDate颿°ãSQLã«å€æããæ¹æ³ãçè§£ããŠããªããããå®è¡æã«ã¯ã©ãã·ã¥ããŸãã æéããªããªããã¿ã¹ã¯ãåŸèŒ©ã«å±ããå Žåã圌ã¯ããã«æ¬¡ã®ãããªãã¡ã€ã«ã§ã³ãŒãããä»äžãããŸãã
repo.Query().ToEnumerable().Where(a => a.CreationDate < getCurrentDate());
ãŸãã300äžã®ã¢ã«ãŠã³ãã¯ãã¹ãŠRAMã«æ ŒçŽãããŸãã
IQueryableãåºåããããšã«ã¯ãŸã æé»çãªåé¡ããããŸãã- IQueryableããªãŒã¯ããŠããã æããã«LSPã«éåããŠããŸãã ãã£ãŒãããåŒãããã€ãžã§ã¹ããããIQueryableå®è£
ã¯ãã¡ã¢ãªå
ã®ã¿ã§ãã ãã ããã¡ã¢ãªå
ã«ã¯linq2objectããããããIQueryableã¯ç¡æå³ã«ãªããŸãã Whereãªã¯ãšã¹ãã¯ãã³ãŒãã®æœåšçãªé害ãã€ã³ãã§ãã
- ãã¹ãŠã®ããŒã¿ãœãŒã¹ãlinqããµããŒãããŠããããã§ã¯ãããŸããã ããæç¹ã§ããã«ããã¹ãæ€çŽ¢ãå¿
èŠã«ãªããããã䜿çšããŠSphinxãŸãã¯Elasticãå¿
èŠã«ãªããŸãã ãlinq-providerãæžããŸãããããšããææ¡ãçµå¶é£ããã®å¿çãèŠã€ããããšãçããŸãïŒãããŠãã¡ãªã¿ã«æ£ããïŒã åé¡ã¯ãã«ããã¹ãã«éå®ããããããŒã¿ã¯ãããã¯ãŒã¯ãçµç±ããŠãã£ã¹ã¯ã«ä¿åãããã¯ã©ãŠããã¡ã€ã«ã·ã¹ãã ã«ä¿åãããŸãã
- ããŒã¿ããŒã¹ãããŒã¿ãœãŒã¹ãšããŠæ©èœããå Žåã§ããããã©ãŒãã³ã¹ã®ç®çã§ãããŒã¿ã®äžéšã鿣èŠåããã圢åŒã§ããããNOSQLãœãªã¥ãŒã·ã§ã³ã«è»¢éãããå¯èœæ§ããããŸãã ã¯ãšãªãæã§æžããŠããã¹ãŠãæå€§éã«èª¿æŽããå¿
èŠãããå¯èœæ§ããããŸãã ãããã³ã°ãªããžã§ã¯ã
æåã®åé¡ã¯ååãšããŠè§£æ±ºãããŸããã ããã¯ãlinqã®èšèšã«ããèšèšãããŠããŸãã æå¥ãèšãã®ã¯çœªã§ããlinqã¯ãšãŠã䟿å©ã§ãã é
ç®2ããã³3ã¯ãå®éã«ã¯IQueryableããã¹ãŠã®å Žé¢ã§æœè±¡åãšããŠé©åã§ã¯ãªãããšã瀺åããŠããŸãããªããªããå®éã®äžçã§ã¯ããã¹ãŠã®.NETéçºè
ãããŒãããã¯ã§åŒããªãŒãè§£æããŠãä»»æã®ããŒã¿ãœãŒã¹ã«ã
ã¿ããªããã§ã«ç§ãã¡ã®ããã«æ¥ãŠãããŠããããã§ã
仿§å¥åãã£ã«ã¿ãŒ
public interface ISpecification<in T> where T:IEntity { bool IsSatisfiedBy(T o); } public interface IRepository<T> { T GetById(int id); // IEnumerable<T> GetBySpecification(ISpecification<T> spec); bool Add(T entity); bool Remove(T entity); }
仿§ã¯ããžãã¹ãã£ã«ã¿ãªã³ã°ã«ãŒã«ã§ãã ãªããžã§ã¯ããæ¡ä»¶ãæºãããŠãããã©ããã瀺ãã¡ãœããã¯1ã€ã ãã§ãã çŸåšã®åœ¢åŒã§ã¯ã仿§ã¯ã³ãŒãã®éè€ã®åé¡ã解決ããŸããLinqããªããåãã£ã«ã¿ãªã³ã°ã«ãŒã«ã«å¯ŸããŠç¬èªã®ä»æ§ã¯ã©ã¹ãèšè¿°ããå¿
èŠããããŸãã
ãããããã¿ãŸããããªããããå¿
èŠãªã®ã§ããïŒ IsSatisfiedByãSQLã«å€æããããšã¯ã§ããŸãããã€ãŸããããŒã¿ããŒã¹ãããã¹ãŠã®ã¬ã³ãŒããå床ååŸãããããã§ãã£ã«ã¿ãªã³ã°ããå¿
èŠããããŸãã ããã§ããããã¿ããšã«ä»æ§ãäœæããå¿
èŠããããŸããããã¯ãïŒç¹å®ã®æ¹æ³ã§ããŒã¿ããã£ã«ã¿ãªã³ã°ããå¿
èŠãããã€ã³ã¿ãŒãã§ãŒã¹ã®ä»£ããã«ïŒäžåºŠã ã䜿çšãããå€ãã®ã¯ã©ã¹ãäœæããããšãæå³ããŸãã
å®éãå
šäœã®è°è«ãé²è¡äžã§ããã
ã仿§ãã®
ãã¿ãŒã³ã¯linqã®åºçŸã«ããæä»£é
ãã«ãªã£ããšåœŒãã¯èšã
ãŸã ã
建ç¯å®å®é£è¡å£«ãæåã«æäŸããããšã¯æ¬¡ã®ãšããã§ãã
public interface IExpressionSpecification<T> : ISpecification<T> where T:class,IEntity { Expression<Func<T, bool>> Expression { get; } } public interface IRepository<T> { T GetById(int id);
åãåµã仿§ã®åœ¢ã§è¿œå ã®äžå¿
èŠãªã¬ã€ã€ãŒãæã€ãããã¡ã€ã«ãã¥ãŒã衚瀺ããããã«ãã¹ãŒããŒãã¯ãŒãæã€å¿
èŠã¯ãããŸããã ããã«ãã³ãŒãå
ã®linqã¯ãšãªã®éè€ã®åé¡ã¯ã次ã®ããã«ãšã¬ã¬ã³ãã«è§£æ±ºã§ããŸãã
public class Account : IEntity { [BusinessRule] public static Expression<Func<Lead, bool>> ActiveRule = x => x.IsDeleted && x.Ballance > 0; }
æåŸã«
- ãªããžããªã¯ããã¹ãŠã®ããŒã¿ãœãŒã¹ã®åºæ¬çãªæœè±¡åãšããŠå¹æçã«äœ¿çšããããšã¯ã§ããŸãã
- linqã¯éåžžã«äŸ¿å©ã§ãããçµæžçãªçç±ãããã©ãŒãã³ã¹ã®å¶éã®ããã«ã©ãã«ãé©ããŠããŸãã
CQ [R] S-ã³ãã³ããã¯ãšãª[責任]åé¢
ãŸãã¯ããã·ã¢èªã§ã®èªã¿åããšæžã蟌ã¿ã®åé¢ã ååã¯ãããŒããããã·ã¹ãã ã§æå€§ã®ã¢ããªã±ãŒã·ã§ã³ãèŠã€ããŸããã å€å
žçãªäŸã¯ããœãŒã·ã£ã«ãããã¯ãŒã¯äžã®ãã£ãŒãã§ãããã¹ãŠã®å人ã®ããŒãã«ã®å±±ããããŒã¿ãååŸããå¿
èŠãããã誰ããããªãã®åçãã©ã®ããã«æ°ã«å
¥ã£ãŠåæçš¿ããããèæ
®ããããšãå¿ããªãã§ãã ããã åŸæ¥ã®å®è£
ã¯ãã®ã¿ã¹ã¯ã«ã¯é©ããŠããŸãã-çµåãšèªã¿åã/æžã蟌ã¿ããã¯ãå€ãããŸãã
äžè¬çãªè§£æ±ºçã¯ãèªã¿åããšæžã蟌ã¿ãåé¢ããŠããããã³ã°ãåé¿ããããšã§ãã ããããã€ãŒãŒã·ã§ã³æŠç¥ã¯ç°ãªãå ŽåããããŸãããäž»ãªãã€ã³ãã¯æ¬¡ã®ãšããã§ãã
- çµåãåãé€ãããã©ããããŒã¿ãèªã¿åããŸã
- èªã¿åã/æžã蟌ã¿ããã¯ãåé¿ãã
- ãããã¯ã°ã©ãŠã³ãã§ãããŒã¿ãåæãã倿Žãèç©ãã
ãããã£ãŠãã¯ã©ã·ãã¯ãªããžããªã¯ãã³ãã³ããšã¯ãšãªã®2ã€ã®ã€ã³ã¿ãŒãã§ã€ã¹ã«åãããŠããŸãã
ã³ãã³ãã¯è¿œå ã倿Žãããã³åé€ãå®è£
ããã¯ãšãªã¯ããŒã¿ã®èªã¿åããå®è£
ããŸãã
public interface IQuery<TEntity, in TSpecification> where TEntity : class, IEntity where TSpecification : ISpecification<TEntity> { IQuery<TEntity, TSpecification> Where([NotNull] TSpecification specification); IQuery<TEntity, TSpecification> OrderBy<TProperty>( [NotNull] Expression<Func<TEntity, TProperty>> expression, SortOrder sortOrder = SortOrder.Asc); IQuery<TEntity, TSpecification> Include<TProperty>([NotNull] Expression<Func<TEntity, TProperty>> expression); [NotNull] TEntity Single(); [CanBeNull] TEntity FirstOrDefault(); [NotNull] IEnumerable<TEntity> All(); [NotNull] IPagedEnumerable<TEntity> Paged(int pageNumber, int take); long Count(); } public interface ICommand { void Execute(); } public interface ICommand<in T> { void Execute(T context); } public interface IPagedEnumerable<out T> : IEnumerable<T> { long TotalCount { get; } } public class CreateEntityCommand<T> : UnitOfWorkScopeCommand<T> where T: class, IEntity { public override void Execute(T context) { UnitOfWorkScope.GetFromScope().Save(context); UnitOfWorkScope.GetFromScope().Commit(); } public CreateEntityCommand([NotNull] IScope<IUnitOfWork> unitOfWorkScope) : base(unitOfWorkScope) { } } public class DeleteEntityCommand<T> : UnitOfWorkScopeCommand<T> where T: class, IEntity { public DeleteEntityCommand([NotNull] IScope<IUnitOfWork> unitOfWorkScope) : base(unitOfWorkScope) { } public override void Execute(T context) { UnitOfWorkScope.GetFromScope().Delete(context); UnitOfWorkScope.GetFromScope().Commit(); } }
ã¯ãšãªã®äž»ãªåœ¹å²ã¯ã仿§ïŒãã¡ã€ã³ãã£ã«ã¿ã«ãŒã«ïŒãããŒã¿ãœãŒã¹ïŒã€ã³ãã©ã¹ãã©ã¯ãã£ïŒã®ã¯ãšãªã«å€æããããšã§ãã ã¯ãšãªã¯ããŒã¿ãœãŒã¹ããã®æœè±¡åãæäŸããŸã-ããŒã¿ã®ååŸå
ã¯é¢ä¿ãªãã仿§ã¯linq +ã®äžçš®ã§ãã linqããµããŒãããããŒã¿ãœãŒã¹ã®å ŽåãExpressionSpecificationã䜿çšã§ããŸãã linqã®äœ¿çšãå°é£ãªå ŽåïŒElastic Searchã®å Žåã®ããã«ãããã€ããŒãååšããªãå Žåãªã©ïŒãåŒãã¹ããŒããŠä»æ§ã䜿çšããŸãã
public interface IExpressionSpecification<T> : ISpecification<T> where T:class,IEntity { Expression<Func<T, bool>> Expression { get; } } public static IQuery<TEntity, IExpressionSpecification<TEntity>> Where<TEntity>( this IQuery<TEntity, IExpressionSpecification<TEntity>> query, Expression<Func<TEntity, bool>> expression) where TEntity : class, IEntity { return query.Where(new ExpressionSpecification<TEntity>(expression)); }
仿§ã®ã€ã³ã¹ã¿ã³ã¹ã䜿çšããŠãRAMå
ã®ããŒã¿ããã£ã«ã¿ãŒåŠçãã仿§ãã¯ãšãªã«å€æããŠãããŒã¿ãœãŒã¹ãžã®ã¯ãšãªãã¯ãšãªã«äŸåãããããšãã§ããŸãã
ICommandFactoryãIQueryFactory
倿°ã®å°ããªã³ãã³ãããã³ã¯ãšãªãªããžã§ã¯ãã®äœæã¯éå±ãªäœæ¥ã«ãªãå¯èœæ§ããããŸããæ
£äŸã«åŸã£ãŠIOCã³ã³ããã«ç»é²ããã®ã¯è«ççã§ãã ã³ã³ããããã¹ãŠã®ã¢ã»ã³ããªã«ãã©ãã°ãããServiceLocatorãäœæããªãããã«ããã®è²¬ä»»ããã¡ã¯ããªã«å²ãåœãŠãŸãã
public interface ICommandFactory { TCommand GetCommand<TEntity, TCommand>() where TCommand : ICommand<TEntity>; T GetCommand<T>() where T : ICommand; CreateEntityCommand<T> GetCreateCommand<T>() where T : class, IEntity; DeleteEntityCommand<T> GetDeleteCommand<T>() where T : class, IEntity; } public interface IQueryFactory { IQuery<TEntity, IExpressionSpecification<TEntity>> GetQuery<TEntity>() where TEntity : class, IEntity; IQuery<TEntity, TSpecification> GetQuery<TEntity, TSpecification>() where TEntity : class, IEntity where TSpecification : ISpecification<TEntity>; TQuery GetQuery<TEntity, TSpecification, TQuery>() where TEntity : class, IEntity where TSpecification: ISpecification<TEntity> where TQuery : IQuery<TEntity, TSpecification>; }
次ã«ãã¯ãšãªã®æäœã¯æ¬¡ã®ããã«ãªããŸã
_queryFactory.GetQuery<Product>() .Where(Product.ActiveRule) // , Account. ExpressionSpecification .OrderBy(x => x.Id) .Paged(0, 10) // 10 // ElasticSearch, : _queryFactory.GetQuery<Product, FullTextSpecification>() .Where(new FullTextSpecification(«»)) .All() // EF Dapper _queryFactory.GetQuery<Product, DictionarySpecification, DapperQuery>() .Where(new DictionarySpecification (someDirctionary)) .All()
ãã¹ãŠã®å Žåã§ãåãã³ãŒãã䜿çšãã_queryFactory.GetQuery <ProductãDictionarySpecificationãDapperQuery>ïŒïŒæ§é ã¯ããããæé©åã§ããããšãæç€ºçã«ç€ºããŠããŸãã
ãã®è¡ã¯ãé²åã®ãªãã¡ã¯ã¿ãªã³ã°äžã«ã®ã¿ã³ãŒãã«è¡šç€ºãããŸãããããã¯ãæåã¯éçºé床ã®ããã«ORMã§èšè¿°ããããã§ããããŒã å
ã«åŒããªãŒã«ç²ŸéããŠãã人ãããå Žåããã¹ãŠã®èŠæ±ãåŸã
ã«linqã«ç¿»èš³ã§ããŸãïŒå®éã®ç掻ã§ã¯ãçµæžçãªçç±ããããã¯ã»ãšãã©äžå¯èœã§ãïŒã_queryFactory.GetQuery <ProductãFullTextSpecification>ïŒïŒã®å Žåãããã«ããã¹ã仿§ããæå®ããŸããããã¡ã€ã³ã³ãŒãã¯è¿ãããã€ã³ã¹ã¿ã³ã¹ïŒElasticSearchQueryïŒã«ã€ããŠäœãç¥ããŸããã圌ã«ãšã£ãŠãããã¯åãªãå
šææ€çŽ¢ãã£ã«ã¿ãªã³ã°ã«ãŒã«ã§ããè«äºïŒhabrahabr.ru/post/125720å°ãæ§æç³
äŸã«æ»ããŸãã public class Account : IEntity { [BusinessRule] public static Expression<Func<Lead, bool>> ActiveRule = x => x.IsDeleted && x.Ballance > 0; bool IsActive() {
ãã¢ã¯ãã£ãã¢ã«ãŠã³ããããžãã¹ã«ãŒã«ã¯è«ççãªå Žæã«é
眮ãããåå©çšãããŸãããããžã§ã¯ãå
šäœã«æ£åšããã©ã ããæããå¿
èŠã¯ãããŸããããã®èŠä»¶ã¯ãExpression <Func <Leadãbool >>ã®åœ¢åŒã§å¿
èŠã«ãªãå ŽåããããŸã-ããŒã¿ãœãŒã¹ãžã®ã¯ãšãªãžã®å€æã®ããã«å¿
èŠãªå ŽåããããŸãããã¹ãŠã®äººã®ããã«ä»æ§ã¯ã©ã¹ãäœæããããšã¯ãè¯ãã¢ã€ãã¢ãšã¯æããŸãããæ¬¡ã®å®è£
ããã€äœ¿çšã§ããŸããïŒ public static class Extensions { private static readonly ConcurrentDictionary<Expression, object> _cachedFunctions = new ConcurrentDictionary<Expression, object>(); public static Func<TEntity, bool> AsFunc<TEntity>(this object entity, Expression<Func<TEntity, bool>> expr) where TEntity: class, IEntity { //@see http://sergeyteplyakov.blogspot.ru/2015/06/lazy-trick-with-concurrentdictionary.html return (Func<TEntity, bool>)_cache.GetOrAdd(expr, id => new Lazy<object>( () => _cache.GetOrAdd(id, expr.Compile()))); } public static bool Is<TEntity>(this TEntity entity, Expression<Func<TEntity, bool>> expr) where TEntity: class, IEntity { return AsFunc(entity, expr).Invoke(entity); } public static IQuery<TEntity, IExpressionSpecification<TEntity>> Where<TEntity>( this IQuery<TEntity, IExpressionSpecification<TEntity>> query, Expression<Func<TEntity, bool>> expression) where TEntity : class, IEntity { return query .Where(new ExpressionSpecification<TEntity>(expression)); } } public class ExpressionSpecification<T> : IExpressionSpecification<T> where T:class,IEntity { public Expression<Func<T, bool>> Expression { get; private set; } private Func<T, bool> _func; private Func<T, bool> Func { get { return this.AsFunc(Expression); } } public ExpressionSpecification([NotNull] Expression<Func<T, bool>> expression) { if (expression == null) throw new ArgumentNullException("expression"); Expression = expression; } public bool IsSatisfiedBy(T o) { return Func(o); } } public class Account : IEntity { [BusinessRule] public static Expression<Func<Lead, bool>> ActiveRule = x => x.IsDeleted && x.Ballance > 0; bool IsActive() { this.Is(ActiveRule); } }
ãµãŒãã¹ããããŒãžã£ãŒããã«ããŒã¯ã©ãã«ããŸããïŒ
ã³ãŒããé©åã«ç·šæãããŠããã°ããã¡ã€ã³ã«helper'ovã¯ãããŸããããã¬ãŒã³ããŒã·ã§ã³å±€ã«äœããããã®ãââããããŸããã ManagerãšServiceã¯åããã®ãªã®ã§ãManagerãšããååããŸã£ãã䜿çšããªãæ¹ãè¯ãã§ãããããµãŒãã¹ã¯çŽç²ã«æè¡çãªçšèªã§ãã Serviceãæ¥å°ŸèŸãšããŠã®ã¿äœ¿çšãããããŸã£ãã䜿çšããŸããïŒIOCã®åæã«ããç»é²ããããã«åå空éã®ã¿ãæ®ããŸãïŒãå®éã®ããžãã¹ã«ã¯ããµãŒãã¹ãã¯ãªããããã£ãã·ã¥ãã¹ã¯ããããã¹ãã£ã³ã°ãããã¯ã©ãŒã¿ããªã©ããããŸãããã®ãããã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã³ã«åŸã£ãŠããžãã¹ããžãã¯ãšååã¯ã©ã¹ãã°ã«ãŒãåããå¿
èŠãªå Žåã«ã®ã¿äœæããããšããå§ãããŸãã CRUDæäœã«ãµãŒãã¹ã¯å¿
èŠãããŸããã UoW + Command + Query + Specification + Validatorã®ãã³ãã«ã¯ãäŒèšã·ã¹ãã ã®ããŒãºã®90ïŒ
ãã«ããŒããã®ã«ååã§ããã¡ãªã¿ã«ãããã«ã¯1ã€ã®ã³ã³ãããŒã©ãŒã¯ã©ã¹ã®ã¿ãå¿
èŠã§ãããããã«
ãã®ãããªã¢ãŒããã¯ãã£ã¯éè² è·ã«èŠãããããããŸãããå®éããã®ãããªã¢ãããŒãã«ã¯ç¹å®ã®å¶éããããŸãã- éçºè
ã®è³æ ŒïŒããã°ã©ãã³ã°ãã¿ãŒã³ã®çè§£ãšãã©ãããã©ãŒã ã®ååãªç¥èãå¿
èŠã§ãã
- ã€ã³ãã©ã¹ãã©ã¯ãã£ã³ãŒããžã®åææè³ïŒãããžã§ã¯ãããã€ã³ã¿ãŒãã§ã€ã¹ãååŸããäžèŠãªäŸåé¢ä¿ãè§£ããã€ã³ãã©ã¹ãã©ã¯ãã£ãã§ããã ãæœè±¡çã§è»œéã«ããããã«ãã«ã¿ã€ã ã§ã»ãŒ4æ¥ããããŸããã
- å®éã®ãããžã§ã¯ãã§ãã¹ãã«åæ ŒããŠããã®ã¯ãã®ã¢ã»ã³ããªã§ãããã¡ããªãã¯ã¯ãªãããã®ã¢ãããŒããæšæºåã«ããããã©ãŒãã³ã¹ã®åäžãä¿èšŒããããšãä¿èšŒããŸãïŒäž»èгçã«ã¯ãããã¯100ïŒ
確信ããŠããŸãïŒ
ã¡ãªãã
- ã€ã³ãã©ã¹ãã©ã¯ãã£ããã®ãã¡ã€ã³ã®æç¢ºãªåé¢
- , , , , ,
- -
- repair-kit
- ,
ç¶ç¶ããã«ã¯...