äŒæ¥ããããžã§ã¯ããåŸæ¥å¡ã®ç®¡çã·ã¹ãã ã¯ãç§ãã¡ã®ç掻ã«é·ãå«ãŸããŠããŸãã ãããŠããã®ãããªãšã³ã¿ãŒãã©ã€ãºã¢ããªã±ãŒã·ã§ã³ã®ãŠãŒã¶ãŒã¯ãŸããŸãèŠæ±ãå³ãããªããŸããã¹ã±ãŒã©ããªãã£èŠä»¶ãããžãã¹ããžãã¯ã®è€éããå¢ããã·ã¹ãã èŠä»¶ãæ¥éã«å€åãããªã¢ã«ã¿ã€ã ã§ã¬ããŒããå¿ èŠã«ãªããŸãã
ãããã£ãŠãéçºäžã«ãã³ãŒããšã¢ãŒããã¯ãã£ã®æŽçãããã³ãããã®è€éåã«ãããŠãåãåé¡ããã°ãã°èŠ³å¯ã§ããŸãã ééã£ãèšèšã¢ãããŒãã§ã¯ãé ããæ©ãããã³ãŒããéåžžã«è€éã§æ··ä¹±ããå€æŽããšã«ããå€ãã®æéãšãªãœãŒã¹ãå¿ èŠã«ãªãç¬éãæ¥ããããããŸããã
å žåçãªã¢ããªã±ãŒã·ã§ã³èšèšã¢ãããŒã
éå±€åã¢ãŒããã¯ãã£ã¯ãWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããæãäžè¬çãªæ¹æ³ã®1ã€ã§ãã äžã®å³ã®ããã«ããã®ç°¡åãªããªãšãŒã·ã§ã³ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯ããŒã¿ã¬ã€ã€ãŒãããžãã¹ããžãã¯ã¬ã€ã€ãŒããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã¬ã€ã€ãŒã®3ã€ã®éšåã«åãããŠããŸãã
ããŒã¿ã¬ã€ã€ãŒã«ã¯ç¹å®ã®ãªããžããªããããããŒã¿ãŠã§ã¢ããŠã¹ããç§ãã¡ãåŒãé¢ããŸãã
ããžãã¹ããžãã¯ã¬ã€ã€ãŒã«ã¯ãããžãã¹ã«ãŒã«ãã«ãã»ã«åãããªããžã§ã¯ãããããŸãïŒéåžžãååã¯Services / BusinessRules / Managers / Helperså ã§ç°ãªããŸãïŒã ãŠãŒã¶ãŒãªã¯ãšã¹ãã¯UIããããžãã¹ã«ãŒã«ãéãã次ã«ãªããžããªãéããããŒã¿ãŠã§ã¢ããŠã¹ã®æäœãå®è¡ãããŸãã
ãã®ã¢ãŒããã¯ãã£ã§ã¯ãããŒã¿ã®åä¿¡ãšå€æŽã®èŠæ±ã¯éåžžãããžãã¹ããžãã¯å±€ã®åãå Žæã§è¡ãããŸãã ããã¯ã³ãŒããæŽçããããã®éåžžã«ã·ã³ãã«ã§éŠŽæã¿ã®ããæ¹æ³ã§ããããã®ãããªã¢ãã«ã¯ã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã«é©ããŠããŸãããããã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããŠãŒã¶ãŒã®æ°ãæéã®çµéãšãšãã«å€§ããå€åãããã¢ããªã±ãŒã·ã§ã³ã«å€§ããªè² è·ããããããæ©èœã®å€§å¹ ãªæ¡åŒµãå¿ èŠãªââãå Žå
ããããWebãªãœãŒã¹ãéåžžã«äžè¬çã«ãªã£ãå Žåã1ã€ã®ãµãŒããŒã§ã¯ååã§ã¯ãªããšããçåãçããå ŽåããããŸãã ãããŠãè€æ°ã®ãµãŒããŒéã®è² è·åæ£ã®åé¡ãçããŸãã è² è·ããã°ããåæ£ããæãç°¡åãªãªãã·ã§ã³ã¯ããªãœãŒã¹ãšããŒã¿ããŒã¹ã®è€è£œã®è€æ°ã®ã³ããŒã䜿çšããããšã§ãã ãããŠããã®ãããªã·ã¹ãã ã®ãã¹ãŠã®ã¢ã¯ã·ã§ã³ã決ããŠåé¢ãããŠããªãããšãèãããšãããã¯æ°ããåé¡ãçã¿åºããŸãã
åŸæ¥ã®å€å±€ã¢ãŒããã¯ãã£ã§ã¯ããã®ãããªåé¡ãç°¡åã«è§£æ±ºããããšã¯ã§ããŸããã ãããã£ãŠããããã®åé¡ãæåãã解決ããã¢ãããŒãã䜿çšãããšããã§ãããã ãã®ãããªã¢ãããŒãã®1ã€ãCQRSã§ãã
ã³ãã³ããšã¯ãšãªã®è²¬ä»»åé¢ïŒCQRSïŒ
CQRSã¯ãç¶æ ãå€æŽããã³ãŒããããã®ç¶æ ãåã«èªã¿åãã³ãŒãããåé¢ãããœãããŠã§ã¢èšèšã¢ãããŒãã§ãã ãã®åé¢ã¯è«ççã§ãããŸããŸãªã¬ãã«ã«åºã¥ããŠããŸãã ããã«ãç©ççã§ãç°ãªãå±€ãŸãã¯ã¬ãã«ãå«ããããšãã§ããŸãã
ãã®ã¢ãããŒãã¯ãã³ãã³ãã¯ãšãªåé¢ïŒCQSïŒã®åçã«åºã¥ããŠããŸãã
CQSã®äž»ãªèãæ¹ã¯ããªããžã§ã¯ãã«ã¯2ã€ã®ã¿ã€ãã®ã¡ãœãããååšã§ãããšããããšã§ãã
- ã¯ãšãªïŒã¡ãœããã¯ããªããžã§ã¯ãã®ç¶æ ãå€æŽããã«çµæãè¿ããŸãã ã€ãŸããã¯ãšãªã«ã¯å¯äœçšã¯ãããŸããã
- ã³ãã³ãïŒã¡ãœããã¯ãå€ãè¿ããã«ãªããžã§ã¯ãã®ç¶æ ãå€æŽããŸãã
ãã®åé¢ã®äŸã«ã€ããŠã¯ã1ã€ã®IsEmailValidã¡ãœãããæã€Userã¯ã©ã¹ãæ€èšããŠãã ããã
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
public class User { public string Email { get ; private set ; } public bool IsEmailValid( string email) { bool isMatch = Regex .IsMatch( "email pattern" , email); if (isMatch) { Email = email; // Command } return isMatch; // Query } }
ãã®ã¡ãœããã§ã¯ãéä¿¡ãããé»åã¡ãŒã«ãæå¹ãã©ãããåãåãããŸãïŒã¯ãšãªãå®è¡ããŸãïŒã ã¯ãã®å Žåã¯Trueããã以å€ã®å Žåã¯FalseãååŸããŸãã ããã§ã¯ãå€ãè¿ãããšã«å ããŠãæå¹ãªé»åã¡ãŒã«ã®å Žåããã®å€ïŒã³ãã³ããå®è¡ïŒãããã«[é»åã¡ãŒã«]ãã£ãŒã«ãã«å²ãåœãŠãããšã決å®ãããŠããŸãã
ãã®äŸã¯éåžžã«åçŽã§ããã«ããããããããã¹ãã®ããã€ãã®ã¬ãã«ã§åŒã³åºããããšãã«ããŸããŸãªãªããžã§ã¯ãã®ç¶æ ãå€æŽããQueryã¡ãœãããæ³åããã°ãããã»ã©ããããªç¶æ³ãå¯èœã§ãã æè¯ã®å Žåãåæ§ã®ã¡ãœãããšãã®é·ããããã°ãåŠçããå¿ èŠããªãå Žåã幞éã§ãã QueryãåŒã³åºãããšã«ãããããã®å¯äœçšã¯ãã·ã¹ãã ãã©ã®ããã«æ©èœããããç解ããã®ãé£ããããããã°ãã°èœèãããããŸãã
CQSã®ååã䜿çšããã¡ãœãããã³ãã³ããšã¯ãšãªã«åå²ãããšã次ã®ã³ãŒããååŸãããŸãã
- ãããªãã¯ã¯ã©ã¹ User
- {
- ãããªãã¯ã¹ããªã³ã°ã¡ãŒã«{ get ; ãã©ã€ããŒãã»ãã ; }
- public bool IsEmailValidïŒ string emailïŒ //ã¯ãšãª
- {
- Return Regex .IsMatchïŒ "email pattern" ãemailïŒ;
- }
- public void ChangeEmailïŒ string emailïŒ //ã³ãã³ã
- {
- if ïŒIsEmailValidïŒemailïŒ== false ïŒ
- throwæ°ãã ArgumentOutOfRangeException ïŒé»åã¡ãŒã«ïŒ;
- ã¡ãŒã«=ã¡ãŒã«;
- }
- }
ããã§ãã¯ã©ã¹ã®ãŠãŒã¶ãŒã¯IsEmailValidãåŒã³åºãããšãã«ç¶æ ã®å€åãèŠãããšããªããªããçµæãåŸãããã ãã§ã-é»åã¡ãŒã«ãæå¹ãã©ããã ãŸããChangeEmailã¡ãœãããåŒã³åºããšããŠãŒã¶ãŒã¯ãªããžã§ã¯ãã®ç¶æ ãæ瀺çã«å€æŽããŸãã
ã¯ãšãªã«ã¯ãCQSã«1ã€ã®æ©èœããããŸãã Queryã¯ãªããžã§ã¯ãã®ç¶æ ãäžåå€æŽããªããããQueryã¿ã€ãã®ã¡ãœããã䞊ååããŠãèªã¿åãæäœã«èµ·å ããè² è·ãåé¢ã§ããŸãã
CQSãã¡ãœããã§åäœããå ŽåãCQRSã¯ãªããžã§ã¯ãã®ã¬ãã«ãŸã§äžæããŸãã Commandã¯ã©ã¹ã¯ã·ã¹ãã ã®ç¶æ ãå€æŽããããã«äœæããã Queryã¯ã©ã¹ã¯ããŒã¿ãååŸããããã«äœ¿çšãããŸãã ãããã£ãŠãã·ã¹ãã ã®ç¶æ ãå€æŽãããªããžã§ã¯ãã®ã»ãããšãããŒã¿ãè¿ããªããžã§ã¯ãã®ã»ãããååŸããŸãã
UIãããžãã¹ããžãã¯ãããŒã¿ããŒã¹ãããå žåçãªã·ã¹ãã èšèšïŒ
CQRSã¯ãCommandãªããžã§ã¯ããšQueryãªããžã§ã¯ããæ··åšãããå¿ èŠã¯ãªããæ瀺çã«éžæããå¿ èŠããããšè¿°ã¹ãŠããŸãã ãã®ããã«åå²ãããã·ã¹ãã ã¯ããã§ã«æ¬¡ã®ããã«ãªã£ãŠããŸãã
CQRSãè¿œæ±ããåé¢ã¯ãããã¬ãã«ã§ã¯ãšãªæäœãã°ã«ãŒãåããå¥ã®ã¬ãã«ã§ããŒã ãã°ã«ãŒãåããããšã«ãã£ãŠå®çŸãããŸãã åã¬ãã«ã«ã¯ç¬èªã®ããŒã¿ã¢ãã«ãç¬èªã®ãµãŒãã¹ã»ããããããç¬èªã®ãã³ãã¬ãŒããšãã¯ãããžãŒã®çµã¿åããã䜿çšããŠäœæãããŸãã ããã«éèŠãªããšã«ããããã®2ã€ã®ã¬ãã«ã¯2ã€ã®ç°ãªãéå±€ã«é 眮ããããšãã§ããçžäºã«åœ±é¿ãäžããããšãªãåå¥ã«æé©åã§ããŸãã
ã³ãã³ããšã¯ãšãªã2ã€ã®ç°ãªããã®ã§ããããšãç解ããã ãã§ããœãããŠã§ã¢ã¢ãŒããã¯ãã£ã«å€§ããªåœ±é¿ããããŸãã ããšãã°ããµããžã§ã¯ããšãªã¢ã®åã¬ãã«ãäºæž¬ããã³ãšã³ã³ãŒãããããšãçªç¶å®¹æã«ãªããŸãã ã³ãã³ãã¹ã¿ãã¯ã®ãã¡ã€ã³ã¬ã€ã€ãŒã«å¿ èŠãªã®ã¯ãã¿ã¹ã¯ãå®äºããããã®ããŒã¿ãããžãã¹ã«ãŒã«ãããã³ã»ãã¥ãªãã£ã«ãŒã«ã®ã¿ã§ãã äžæ¹ãã¯ãšãªã¹ã¿ãã¯ã®ãã¡ã€ã³ã¬ãã«ã¯ãçŽæ¥SQLã¯ãšãªãããè€éã«ãªãããšã¯ãããŸããã
CQRSã䜿çšããå Žåã®éå§ç¹
1.ããŒã ã¹ã¿ãã¯
CQRSã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ãå€æŽããã¿ã¹ã¯ã®ã¿ãã³ãã³ãã¹ã¿ãã¯ã«å²ãåœãŠãããŸãã ããŒã ã«ã¯æ¬¡ã®ããããã£ããããŸãã
- ã·ã¹ãã ã®ç¶æ ãå€æŽããŸãã
- äœãè¿ããŸããã
- ã³ãã³ãã³ã³ããã¹ãã«ã¯ããã®å®è¡ã«å¿ èŠãªããŒã¿ãæ ŒçŽãããŸãã
ã³ãã³ãã®å®£èšãšäœ¿çšã¯ãæ¡ä»¶ä»ãã§3ã€ã®éšåã«åããããšãã§ããŸãã
- ããŒã¿ãè¡šãã³ãã³ãã¯ã©ã¹ã
- ã³ãã³ããã³ãã©ã¯ã©ã¹ã
- å ¥åã³ãã³ããåãåãããã®ã¿ã€ãã®ã³ãã³ããå®è£ ãããã³ãã©ãŒãæ£ç¢ºã«åŒã³åºãã¡ãœãããå«ãã¯ã©ã¹ã
ã³ãã³ããšã¯ãšãªã®æ¬è³ªã¯ãããããçµåã§ããå ±éã®æ©èœãåããŠããããšã§ãã èšãæããã°ããããã¯å ±éã®ã¿ã€ããæã£ãŠããŸãã ã³ãã³ãã®å Žåã次ã®ããã«ãªããŸãã
- ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ ICommand
- {
- }
æåã®ã¹ãããã¯ãååãšããŠäœãå«ãŸãªãã€ã³ã¿ãŒãã§ãŒã¹ã宣èšããããšã§ãã ããã¯ãã©ã¡ãŒã¿ãŒãšããŠäœ¿çšããããµãŒããŒåŽã§ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ïŒUIïŒããçŽæ¥ååŸããããå¥ã®æ¹æ³ã§åœ¢æããŠã³ãã³ããã³ãã©ãŒã«éä¿¡ã§ããŸãã
次ã«ãã³ãã³ããã³ãã©ã€ã³ã¿ãŒãã§ã€ã¹ã宣èšãããŸãã
- ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ ICommandHandler < in TCommand> where TCommandïŒ ICommand
- {
- void ExecuteïŒTCommandã³ãã³ãïŒ;
- }
åã«å®£èšãããã€ã³ã¿ãŒãã§ã€ã¹ã¿ã€ãã®ããŒã¿ãåãå ¥ããã¡ãœããã1ã€ã ãå«ãŸããŠããŸãã
ãã®åŸãéä¿¡ãããã³ãã³ãïŒICommandïŒã®ç¹å®ã®ã¿ã€ãã«å¿ããŠãã³ãã³ããã³ãã©ãŒãäžå çã«åŒã³åºãæ¹æ³ã決å®ããŸãã ãã®åœ¹å²ã¯ããµãŒãã¹ãã¹ãŸãã¯ãã£ã¹ãããã£ã«ãã£ãŠå®è¡ã§ããŸãã
- ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ ICommandDispatcher
- {
- void Execute < TCommand >ïŒ TCommand commandïŒ where TCommand ïŒICommand;
- }
ããŒãºã«å¿ããŠã1ã€ä»¥äžã®ã¡ãœããã䜿çšã§ããŸãã åçŽãªã±ãŒã¹ã§ã¯ã1ã€ã®ã¡ãœããã§ååãªå Žåãããããã®ã¿ã¹ã¯ã¯ãæž¡ããããã©ã¡ãŒã¿ãŒã®ã¿ã€ãã«ãã£ãŠãåŒã³åºãã³ãã³ããã³ãã©ãŒã®å®è£ ã決å®ããããšã§ãã ãããã£ãŠããŠãŒã¶ãŒã¯ãããæåã§è¡ãå¿ èŠã¯ãããŸããã
ã³ãã³ãäŸ ã ãªã³ã©ã€ã³ã¹ãã¢ããããšããŸããå庫ã«ååãäœæããããŒã ãäœæããå¿ èŠãããããã§ãã ãŸããååã§ãã®ã³ãã³ããå®è¡ããã¢ã¯ã·ã§ã³ã瀺ãã¯ã©ã¹ãäœæããŸãã
- ãããªãã¯ã¯ã©ã¹ CreateInventoryItem ïŒ ICommand
- {
- public Guid InventoryItemid { get ; }
- ãããªãã¯ã¹ããªã³ã° Name { get ; }
- public CreateInventoryItem ïŒ GUID InventoryItemld ã æåååïŒ
- {
- InventoryItemId = inventoryItemId;
- åå=åå;
- }
- }
ICommandãå®è£ ãããã¹ãŠã®ã¯ã©ã¹ã«ã¯ãããŒã¿ïŒåæåäžã«å€ãèšå®ããããããã£ãšã³ã³ã¹ãã©ã¯ã¿ãŒïŒãå«ãŸããŠããŸããããã以äžã®ãã®ã¯ãããŸããã
ãã³ãã©ãŒã®å®è£ ãã€ãŸãã³ãã³ãèªäœãžã®çŽæ¥çãªå®è£ ã¯ãããªãåçŽãªã¢ã¯ã·ã§ã³ã«ãªããŸããICommandHandlerã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããã¯ã©ã¹ãäœæãããŸãã typeåŒæ°ã¯ã以åã«å®£èšãããã³ãã³ãã瀺ããŸãã
- ãããªãã¯ã¯ã©ã¹ InventoryCommandHandler ïŒ ICommandHandler < CreateInventoryItem >
- {
- ãã©ã€ããŒãèªã¿åãå°çš IRepository < InventoryItem > _repository;
- public InventoryCommandHandlersïŒIRepository < InventoryItem > repositoryïŒ
- {
- _repository =ãªããžããª;
- }
- public void ExecuteïŒ CreateInventoryItemã¡ãã»ãŒãžïŒ
- {
- var item = new InventoryItem ïŒmessage.InventoryItemldãmessage.NameïŒ;
- _repository.SaveïŒã¢ã€ãã ïŒ;
- }
- // ...
- }
ãããã£ãŠããã®ã³ãã³ããå ¥åãšããŠåãåããéä¿¡ãããããŒã¿ã«åºã¥ããŠå®è¡ããã¢ã¯ã·ã§ã³ã瀺ãã¡ãœãããå®è£ ããŸãã ã³ãã³ããã³ãã©ãŒãè«ççã«çµã¿åãããŠããã®ãããªã¯ã©ã¹ã®ããŸããŸãªã¿ã€ãã®ã³ãã³ãã§è€æ°ã®ICommandHandlerã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ã§ããŸãã ããã«ãããã¡ãœããããªãŒããŒããŒããããExecuteã¡ãœãããåŒã³åºããããšãé©åãªã³ãã³ãã¿ã€ããéžæãããŸãã
ããã§ãé©åãªã³ãã³ããã³ãã©ãŒãåŒã³åºãã«ã¯ãICommandDispatcherã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããã¯ã©ã¹ãäœæããå¿ èŠããããŸãã æåŸã®2ã€ãšã¯ç°ãªãããã®ã¯ã©ã¹ã¯äžåºŠäœæãããã³ãã³ããã³ãã©ãŒã®ç»é²ãšåŒã³åºãã®æŠç¥ã«å¿ããŠç°ãªãå®è£ ãæã€å ŽåããããŸãã
- ãããªãã¯ã¯ã©ã¹ CommandDispatcher ïŒ ICommandDispatcher
- {
- ãã©ã€ããŒãèªã¿åãå°çš IDependencyResolver _resolver;
- public CommandDispatcher ïŒIDependencyResolverãªãŸã«ããŒïŒ
- {
- _resolver =ã¬ãŸã«ã;
- }
- public void Execute < TCommand >ïŒ TCommand commandïŒ where TCommand ïŒICommand
- {
- if ïŒcommand == null ïŒ throw ArgumentNullException ïŒ "command" ïŒ;
- var handler = _resolver.Resolve < ICommandHandler < TCommand >>ïŒïŒ;
- if ïŒhandler == null ïŒ throw new CommandHandlerNotFoundException ïŒ typeof ïŒ TCommand ïŒïŒ;
- handler.ExecuteïŒã³ãã³ãïŒ;
- }
- }
ç®çã®ã³ãã³ããã³ãã©ãŒãåŒã³åºã1ã€ã®æ¹æ³ã¯ããã¹ãŠã®ãã³ãã©ãŒå®è£ ãç»é²ãããŠããDIã³ã³ãããŒã䜿çšããããšã§ãã éä¿¡ãããã³ãã³ãã«å¿ããŠããã®ã¿ã€ãã®ã³ãã³ããåŠçããã€ã³ã¹ã¿ã³ã¹ãäœæãããŸãã 次ã«ããã£ã¹ãããã£ã¯åã«Executeã¡ãœãããåŒã³åºããŸãã
2.ã¯ãšãªã¹ã¿ãã¯
ã¯ãšãªã¹ã¿ãã¯ã¯ãããŒã¿æœåºã®ã¿ãåŠçããŸãã èŠæ±ã§ã¯ããã¬ãŒã³ããŒã·ã§ã³ã¬ãã«ã§äœ¿çšãããããŒã¿ã«æãäžèŽããããŒã¿ã¢ãã«ã䜿çšãããŸãã ããžãã¹ã«ãŒã«ã¯ã»ãšãã©å¿ èŠãããŸãããéåžžãç¶æ ãå€æŽããããŒã ã«é©çšãããŸãã
ãªã¯ãšã¹ãã«ã¯æ¬¡ã®ããããã£ããããŸãã
- ã·ã¹ãã ã®ç¶æ ãå€æŽããŸããã
- èŠæ±ã³ã³ããã¹ãã«ã¯ããã®å®è¡ã«å¿ èŠãªããŒã¿ïŒããŒãžã³ã°ããã£ã«ã¿ãŒãªã©ïŒãæ ŒçŽãããŸãã
- çµæãè¿ããŸãã
ãªã¯ãšã¹ãã®ã¢ããŠã³ã¹ãšäœ¿çšã¯ãæ¡ä»¶ä»ãã§3ã€ã®éšåã«åããããšãã§ããŸãã
- èŠæ±ã¯ã©ã¹ãè¿ãããçµæã®ã¿ã€ããå«ãããŒã¿ã
- ãªã¯ãšã¹ããã³ãã©ãŒã¯ã©ã¹
- å ¥åã®èŠæ±ãåãå ¥ãããã®ã¿ã€ãã®èŠæ±ãå®è£ ãããã³ãã©ãŒãæ£ç¢ºã«åŒã³åºãã¡ãœãããå«ãã¯ã©ã¹ã
ã³ãã³ããšåæ§ã«ããªã¯ãšã¹ãã«å¯ŸããŠåæ§ã®ã€ã³ã¿ãŒãã§ãŒã¹ã宣èšãããŠããŸãã å¯äžã®éãã¯ãè¿ãããå 容ã瀺ãããšã§ãã
- ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ IQuery < TResult >
- {
- }
ããã§ã¯ãè¿ãããããŒã¿ã®ã¿ã€ããã¿ã€ãåŒæ°ãšããŠç€ºãããŸãã ããã¯ãstringãŸãã¯int []ãªã©ã®ä»»æã®ã¿ã€ãã«ããããšãã§ããŸãã
次ã«ãæ»ãå€ã®åã瀺ãããŠããèŠæ±ãã³ãã©ã宣èšãããŸãã
- ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ IQueryHandler < in TQueryã out TResult > where TQueryïŒIQuery < TResult >
- {
- TResult ExecuteïŒTQueryã¯ãšãªïŒ;
- }
ã³ãã³ããšåæ§ã«ããã£ã¹ãããã£ã¯ãªã¯ãšã¹ããã³ãã©ãåŒã³åºãããã«å®£èšãããŸãã
- ãããªãã¯ã€ã³ã¿ãŒãã§ã€ã¹ IQueryDispatcher
- {
- TResult Execute < TQuery ã TResult >ïŒ TQuery queryïŒ where TQuery ïŒIQuery < TResult >;
- }
ãªã¯ãšã¹ãã®äŸã æ€çŽ¢æ¡ä»¶ã«ãã£ãŠãŠãŒã¶ãŒãè¿ãã¯ãšãªãäœæãããšããŸãã ããã§ã¯ãæå³ã®ããã¯ã©ã¹åã䜿çšããŠãã©ã®ãããªçš®é¡ã®èŠæ±ãè¡ããããã瀺ããŸãã
- ãããªãã¯ã¯ã©ã¹ FindUsersBySearchTextQuery ïŒ IQuery < ãŠãŒã¶ãŒ []>
- {
- ãããªãã¯ã¹ããªã³ã° SearchText { get ; }
- public bool InactiveUsers { get ; }
- ãããªã㯠FindUsersBySearchTextQuery ïŒ æåå searchTextã bool inactiveUsersïŒ
- {
- SearchText = searchText;
- InactiveUsers = inactiveUsers;
- }
- }
次ã«ãã¯ãšãªã®åãšæ»ãå€ã®åã®åŒæ°ã䜿çšããŠIQueryHandlerãå®è£ ãããã³ãã©ãŒãäœæããŸãã
- ãããªãã¯ã¯ã©ã¹ UserQueryHandler ïŒ IQueryHandler < FindUsersBySearchTextQuery ã User []>
- {
- private readonly IRepository < User > _repository;
- ãããªã㯠UserQueryHandlerïŒIRepository < ãŠãŒã¶ãŒ >ãªããžããªïŒ
- {
- _repository =ãªããžããª;
- }
- public User [] ExecuteïŒ FindUsersBySearchTextQueryã¯ãšãªïŒ
- {
- var users = _repository.GetAllïŒïŒ;
- return users.WhereïŒuser => user.Name.ContainsïŒquery.SearchTextïŒïŒãToArrayïŒïŒ;
- }
- }
ãã®åŸããªã¯ãšã¹ããã³ãã©ãåŒã³åºãã¯ã©ã¹ãäœæããŸãã
- ãããªãã¯ã¯ã©ã¹ QueryDispatcher ïŒ IQueryDispatcher
- {
- ãã©ã€ããŒãèªã¿åãå°çš IDependencyResolver _resolver;
- ãããªã㯠QueryDispatcher ïŒIDependencyResolverãªãŸã«ããŒïŒ
- {
- _resolver =ã¬ãŸã«ã;
- }
- public TResult Execute < TQuery ã TResult >ïŒ TQuery queryïŒ where TQuery ïŒIQuery < TResult >
- {
- if ïŒquery == null ïŒ throwæ°ãã ArgumentNullException ïŒ "query" ïŒ;
- var handler = _resolver.Resolve < IQueryHandler < TQuery ã TResult >>ïŒïŒ;
- if ïŒhandler == null ïŒ throw new QueryHandlerNotFoundException ïŒ typeof ïŒ TQuery ïŒïŒ;
- return handler.ExecuteïŒã¯ãšãªïŒ;
- }
- }
ã³ãã³ããšã¯ãšãªãåŒã³åºã
ã³ãã³ããšã¯ãšãªãåŒã³åºãã«ã¯ãé©åãªãã£ã¹ãããã£ã䜿çšããŠãç¹å®ã®ãªããžã§ã¯ããå¿ èŠãªããŒã¿ãšãšãã«è»¢éããã ãã§ååã§ãã ããšãã°ã次ã®ããã«ãªããŸãã
- ãããªãã¯ã¯ã©ã¹ UserController ïŒ Controller
- {
- private IQueryDispatcher _queryDispatcher;
- ãããªã㯠UserController ïŒIQueryDispatcher queryDispatcherïŒ
- {
- _queryDispatcher = queryDispatcher;
- }
- ãããªã㯠ActionResult SearchUsersïŒ æåå searchStringïŒ
- {
- var query = new FindUsersBySearchTextQuery ïŒsearchStringïŒ;
- ãŠãŒã¶ãŒ [] users = _queryDispatcher.ExecuteïŒã¯ãšãªïŒ;
- æ»ããã¥ãŒïŒãŠãŒã¶ãŒïŒ;
- }
- }
ãŠãŒã¶ãŒèŠæ±ãåŠçããããã®ã³ã³ãããŒã©ãŒãããã°ãç®çã®ãã£ã¹ãããã£ãŒã®ãªããžã§ã¯ããäŸåé¢ä¿ãšããŠè»¢éããèŠæ±ãŸãã¯ã³ãã³ããªããžã§ã¯ããäœæããŠããããçŽäºã¡ãœããExecuteã«æž¡ãã ãã§ååã§ãã
ãã®ãããã·ã¹ãã é¢æ°ã®æ°ãå¢ãããŠäŸåé¢ä¿ã絶ããå¢ãããæœåšçãªãšã©ãŒã®æ°ãæžããå¿ èŠæ§ãåãé€ããŸãã
ãã³ãã©ãŒç»é²
ãã³ãã©ãŒã¯ããŸããŸãªæ¹æ³ã§ç»é²ã§ããŸãã DIã³ã³ããã䜿çšããŠãåå¥ã«ç»é²ããããç®çã®ã¿ã€ãã®ã¢ã»ã³ããªãèªåçã«ã¹ãã£ã³ã§ããŸãã 2çªç®ã®ãªãã·ã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
using SimpleInjector;
var container = new Container ();
container.Register( typeof (ICommandHandler<>), AppDomain .CurrentDomain.GetAssemblies());
container.Register( typeof (IQueryHandler<,>), AppDomain .CurrentDomain.GetAssemblies());
ããã¯SimpleInjectorã³ã³ããã䜿çšããŸã ã Registerã¡ãœããã䜿çšããŠãã³ãã©ãŒãç»é²ããå Žåãæåã®åŒæ°ã¯ã³ãã³ããã³ãã©ãŒãšèŠæ±ãã³ãã©ãŒã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ã€ããæå®ãã2çªç®ã¯ãããã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããã¯ã©ã¹ãæ€çŽ¢ãããã¢ã»ã³ããªãæå®ããŸãã ãããã£ãŠãç¹å®ã®ãã³ãã©ãŒãæå®ããå¿ èŠã¯ãªããå ±éã®ã€ã³ã¿ãŒãã§ãŒã¹ã®ã¿ãæå®ããå¿ èŠããããéåžžã«äŸ¿å©ã§ãã
ã³ãã³ã/ã¯ãšãªãåŒã³åºããšãã«ãã¢ã¯ã»ã¹èš±å¯ã確èªãããããã°ã«æ å ±ãæžã蟌ãã ãããå¿ èŠãããå Žåã¯ã©ããªããŸããïŒ
äžå åãããåŒã³åºãã«ããããã³ãã©ãŒãå®è¡ããåãŸãã¯å®è¡ããåŸãã¢ã¯ã·ã§ã³ãå€æŽããããšãªãè¿œå ã§ããŸãã ãã£ã¹ãããã£ãŒèªäœã«å€æŽãå ããããDIã³ã³ãããŒãä»ããŠå ã®å®è£ ã眮ãæãããã³ã¬ãŒã¿ãŒãäœæããã ãã§ååã§ãïŒãã®ãããªãã³ã¬ãŒã¿ãŒã®äŸã«ã€ããŠã¯ãSimpleInjectorã®ããã¥ã¡ã³ãã§è©³ãã説æãããŠããŸãïŒã
CQRSã®å©ç¹
- åã¯ã©ã¹ã®äŸåé¢ä¿ãå°ãªãã
- åç¬è²¬ä»»ã®å°éïŒSRPïŒ;
- ã»ãšãã©ã©ãã«ã§ãé©ããŠããŸãã
- 亀æãšãã¹ããç°¡åã§ãã
- æ©èœãããç°¡åã«æ¡åŒµãããŸãã
CQRSã®å¶é
- CQRSã䜿çšãããšãå€ãã®å°ããªã¯ã©ã¹ã衚瀺ãããŸãã
- åçŽãªCQRSå®è£ ã䜿çšããå Žåãåäžã®ãã©ã³ã¶ã¯ã·ã§ã³ã§ã³ãã³ãã®ã°ã«ãŒãã䜿çšããããšã¯å°é£ã§ãã
- ã³ãã³ããšã¯ãšãªã«å ±éã®ããžãã¯ã衚瀺ãããå Žåãç¶æ¿ãŸãã¯æ§æã䜿çšããå¿ èŠããããŸãã ããã¯ã·ã¹ãã ã®èšèšãè€éã«ããŸãããçµéšè±å¯ãªéçºè ã«ãšã£ãŠé害ã«ã¯ãªããŸããã
- CQSãšCQRSã«å®å šã«åºå·ããããšã¯å°é£ã§ãã æãç°¡åãªäŸã¯ãã¹ã¿ãã¯ããããŒã¿ãååŸããæ¹æ³ã§ãã ããŒã¿ã®ååŸã¯ã¯ãšãªã§ãããç¶æ ãå€æŽããã¹ã¿ãã¯ãµã€ãºã-1ã«ããå¿ èŠããããŸãã å®éã«ã¯ãååã®å³æ Œãªéµå®ãšçç£ã®å¿ èŠæ§ãšã®éã®ãã©ã³ã¹ãæ±ããŸãã
- CRUDã¢ããªã±ãŒã·ã§ã³ã«æªåœ±é¿ãåãŒãã
é©ããªãå Žæ
- å°èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³/ã·ã¹ãã ã®å Žåã
- äž»ã«CRUDã¢ããªã±ãŒã·ã§ã³ã
ãããã«
ã¢ããªã±ãŒã·ã§ã³ãçã«å¹æçã§ããããã«ã¯ãããžãã¹ã®èŠä»¶ã«é©å¿ããå¿ èŠããããŸãã CQRSããŒã¹ã®ã¢ãŒããã¯ãã£ã¯ãããžãã¹ã¯ãŒã¯ãããŒã®æ¡åŒµãšå€æŽãå€§å¹ ã«ç°¡çŽ åããæ°ããã·ããªãªããµããŒãããŸãã æ¡åŒµæ©èœãå®å šã«åé¢ããŠç®¡çã§ããŸãã ãããè¡ãã«ã¯ãæ°ãããã³ãã©ãŒãè¿œå ããŠç»é²ããå¿ èŠãªã¿ã€ãã®ã¡ãã»ãŒãžã®ã¿ãåŠçããæ¹æ³ã圌ã«äŒããŸãã æ°ããã³ã³ããŒãã³ãã¯ãã¡ãã»ãŒãžã衚瀺ããããšãã«ã®ã¿èªåçã«åŒã³åºãããã·ã¹ãã ã®ä»ã®éšåãšäžŠãã§æ©èœããŸãã ç°¡åãã·ã³ãã«ãå¹æçã
CQRSã䜿çšãããšãã³ãã³ããšã¯ãšãªã®ãã€ãã©ã€ã³ãä»»æã®æ¹æ³ã§æé©åã§ããŸãã åæã«ã1ã€ã®ã³ã³ãã€ãŒã®æé©åã«ãããå¥ã®ã³ã³ãã€ãŒã®åäœãäžæãããããšã¯ãããŸããã CQRSã®æãåºæ¬çãªåœ¢åŒã§ã¯ã1ã€ã®å ±éããŒã¿ããŒã¹ã䜿çšãããã¢ããªã±ãŒã·ã§ã³å±€ããã®èªã¿åãããã³æžã蟌ã¿æäœã®ããã«ç°ãªãã¢ãžã¥ãŒã«ãåŒã³åºãããŸãã
ãœãŒã¹
â Alexander Byndyuã®ããã°-CQRSã®å®è·µ
â æåç·-éåžžã®ã¢ããªã±ãŒã·ã§ã³ã®CQRS
â DDDãCQRSãã€ãã³ããœãŒã·ã³ã°ã®è©Šè¡æ¹æ³ãšçµè«
â ã°ã¬ãã°ã€ã³ã°ã«ããCQRSããã¥ã¡ã³ã
â ç°¡åãªCQRSã®äŸ
â DDDDãCQRSãããã³ãã®ä»ã®ãšã³ã¿ãŒãã©ã€ãºéçºã®ããºã¯ãŒã