tag:blogger.com,1999:blog-4689305754522303819.post7132981056057045000..comments2024-03-15T09:17:14.853+01:00Comments on Andy Butland: A CQRS Implementation with ASP.Net MVC and Entity FrameworkAndy Butlandhttp://www.blogger.com/profile/02536557608655499040noreply@blogger.comBlogger22125tag:blogger.com,1999:blog-4689305754522303819.post-30338971522026313132017-11-30T13:21:53.226+01:002017-11-30T13:21:53.226+01:00I want to inject DataContext from UI to CommandHan...I want to inject DataContext from UI to CommandHandler and QueryHandler separately using Ninject. We will have 2 seperate database, 1 for QueryHandler and other for CommandHandler Could you please help me with that?Bhaiyyahttps://www.blogger.com/profile/16089196009167651534noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-61477125716538026772016-11-25T16:53:42.726+01:002016-11-25T16:53:42.726+01:00It's pulled out of a client project, so I coul...It's pulled out of a client project, so I couldn't I'm afraid - but the various pieces are all in the post above.<br /><br />You might want to check out this library though: https://github.com/jbogard/MediatR. Released since this post was written it takes a similar approach and is well documented. I've switched to using it now.Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-56759196832924198202016-11-25T15:24:52.911+01:002016-11-25T15:24:52.911+01:00Hi Andy!
I am new to CQRS.... I read the your blog...Hi Andy!<br />I am new to CQRS.... I read the your blog.. but as not too expert i am unable to get hole CQRS implementation process. So i request you to provide the sample code of said example of your blog. <br /><br />Thank You :) Code Primehttps://www.blogger.com/profile/01877041896555443471noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-26899052090443551812016-09-26T07:55:37.271+02:002016-09-26T07:55:37.271+02:00No, it won't deadlock. It's using asynchr...No, it won't deadlock. It's using asynchronous methods in the sense of using async/await, which allow the application to continue to do other work when waiting for relatively slow operations to complete - such as database access.<br /><br />But it's not asynchronous in the sense of fire and forget. I am waiting for a response from the command to be able to indicate the caller if it were successful or not. Some might say that's a deviation from true CQRS but I think it's also valid to say normally you do want to have the caller know something has successfully accepted.<br /><br />Now it might be you still would want to process the command in a true asynchronous pattern, if it were really slow like perhaps generating a report. I've not done that here but for some applications (or some commands within an application) it might be useful. Even then though, you would probably still want your command to acknowledge the request with a command result - and so not be true fire and forget. That request then might be saved to a queue to be processed via another application.<br /><br />There's more on this here: https://lostechies.com/jimmybogard/2012/08/22/busting-some-cqrs-myths/ - see "myth 4"Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-35955778279994765242016-09-26T07:23:34.811+02:002016-09-26T07:23:34.811+02:00Hi,
First of all thanks for the write up, it was a...Hi,<br />First of all thanks for the write up, it was a great read.<br /><br />I am curious how this handles commands asynchronously, since command handlers are suppose to be "fire and forget" returns nothing (void). However in your example you return CommandResult, wouldn't this cause a deadlock? 12Secondshttps://www.blogger.com/profile/08310191697001189359noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-36866010276071741732016-09-11T10:09:31.260+02:002016-09-11T10:09:31.260+02:00Yes, have referenced that post above - was the mai...Yes, have referenced that post above - was the main source of inspiration for this.Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-83467577830614147032016-09-11T10:06:27.911+02:002016-09-11T10:06:27.911+02:00@Steven check out
http://www.adamtibi.net/06-2013...@Steven check out <br />http://www.adamtibi.net/06-2013/implementing-a-cqrs-based-architecture-with-mvc-and-document-db<br />There's a link to download a solution at the bottom of that page that's very similar to what's described above; with the exception that's it's not async based (though it would be pretty easy to make it async).GFoley83https://www.blogger.com/profile/14066435129292893963noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-25207678213752167412016-09-09T12:03:37.700+02:002016-09-09T12:03:37.700+02:00That's provided by Ninject.That's provided by Ninject.Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-394447558245084272016-09-08T23:02:24.846+02:002016-09-08T23:02:24.846+02:00Hi, what is the IKernel?Hi, what is the IKernel?Tomhttps://www.blogger.com/profile/03884346175488166448noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-31108760161558495592016-04-08T06:18:48.142+02:002016-04-08T06:18:48.142+02:00After dealing with service classes, repositories, ...After dealing with service classes, repositories, unit of work patterns and all that guff I've come to the same architectural conclusion as you - glad to see someone else with the same thoughts!Rowanhttps://www.blogger.com/profile/15333178845730121128noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-91207080499997980422016-02-09T18:25:20.566+01:002016-02-09T18:25:20.566+01:00I'd usually be considering three types of vali...I'd usually be considering three types of validation here.<br /><br />Firstly, if the command has come from a form post with a number of fields, I'd have presented this as a view model with validation in the form of validation attributes. I'd ensure the view model was valid before creating the command (and if not return to the view in the usual MVC way). So that would deal with things like required fields, string lengths and the like.<br /><br />Then as you say there's "business command validation". Things like checking a submitted value is valid based on other things you might need to query (e.g. a unique email address for a registration form). In those cases I'd return a message and success = false flag in the CommandResult and act on that in the controller to add an error to the ModelState and return to the view.<br /><br />And then there's unexpected exceptions. In that case there's a couple of options - if they are potentially recoverable, could put the try/catch in the command handler. But normally I'd just let them bubble up to the controller and handle them there with some error handling that logs the error and present a "unexpected error" page.<br /><br />PS: Thanks!Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-6566955486481950422016-02-09T17:16:32.232+01:002016-02-09T17:16:32.232+01:00how do you handle exception when executing command...how do you handle exception when executing command. I see CommandResult have a Success property. Is this property used just for 'business command validation' (e.g. object is not in a valid state for the command) or u use it also for unexpected exceptions and handle all the exception in the CommandHandler?<br /><br />P.S. : great session at WEC in Milan. Anonymoushttps://www.blogger.com/profile/02614809773718163916noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-13997698018449974912016-01-08T15:57:06.652+01:002016-01-08T15:57:06.652+01:00Interesting one. I think probably if it were me I...Interesting one. I think probably if it were me I'd consider that one "responsibility" and be fine with it in the command. It involves a bit of a logic and additional queries as you say, but it's all to the same end of "updating an object". So feels OK to me... but you or others may disagree.<br /><br />One thing you could perhaps do though is in your query.getMoreInfo() use AsNoTracking()? That way if you did - inadvertently - change any properties on that object they wouldn't get flushed to the database on SaveChanges().Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-11014713707977467832016-01-08T15:19:32.532+01:002016-01-08T15:19:32.532+01:00How do you handle business logic which means you n...How do you handle business logic which means you need to keep the context around?<br /><br />I need to load an object, check some state, possibly load another object, check it's state and then save the initial object with some changes. I can move all that logic into the command but that's not really giving it a single responsibility. <br /><br />I'm currently using a per-request lifetime manager for my DI container and injecting the context into the commands. Calling the command from the BL is then a 2 step process, var toEdit = command.load(); var info = query.getMoreInfo(); toEdit.Something = newValue; command.saveChanges(); <br /><br />The issue i feel is that having that shared context means that any "accidental" changes to info will also be saved. The pattern isn't very clean.Anyonehttps://www.blogger.com/profile/11067446089253219198noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-35050859169522320502015-11-16T16:50:23.354+01:002015-11-16T16:50:23.354+01:00Hi Kilfay - no, these sit in a separate class, the...Hi Kilfay - no, these sit in a separate class, the query handler or command handler as referenced in the diagrams above, something like:<br /><br />public class MyQueryHandler : IQueryHandler[MyViewModeQuery, MyViewModel]<br />{<br />public async Task Retrieve(MyViewModelQueryquery) {}<br />}<br /><br />(Note the square brackets above should be angle brackets, but the commenting tool swallows them).Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-69303753765172866692015-11-16T16:48:27.799+01:002015-11-16T16:48:27.799+01:00This comment has been removed by the author.Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-81071041295402649572015-11-16T15:35:14.360+01:002015-11-16T15:35:14.360+01:00Thanks for the post. I am a bit confuse about the ...Thanks for the post. I am a bit confuse about the implementation of the execute and retrieve methods of the handlers. did you just create an action in the controllerAnonymoushttps://www.blogger.com/profile/02053074797583556787noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-89383063413346923932015-08-07T19:08:13.008+02:002015-08-07T19:08:13.008+02:00Hi Darrell - thanks for the comment. It's not...Hi Darrell - thanks for the comment. It's not the case that I see commands as domain objects no, but it's good you pointed out as I can see that I've made it look like that. I agree with your view that the command object should contain only the information necessary to perform the write operation - so in your case with a "ShipOrderCommand" it would likely contain only the order Id and perhaps the date.<br /><br />Rather it just happens that the command I've used to illustrate my example called "AddOrEditCommand" comes from an example where I need to add (or edit) an Activity (which is a domain object) record. Given the command contains fields like the activity name, location, date that do map to fields on the domain object, I've used Automapper to perform this update. It's as you say a happy coincidence (or perhaps laziness!) on my part that I've done that.Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-43494173111338836662015-08-07T19:02:06.901+02:002015-08-07T19:02:06.901+02:00Thanks for the example - I am new to CQRS and this...Thanks for the example - I am new to CQRS and this helps.<br />A question if I may! Are the commands meant to be similar to domain objects? The usage of: Mapper.Map(command, activity); suggests that they are, however I wouldn't have thought that this was often the case. I'm picturing for example, a "ShipOrderCommand" - it contains the information necessary to ship the order (i.e the order id) but it has nothing to say about your domain model. To process the order shipping in terms of the domain model would probably require all sorts of interactions with domain objects. Am I missing something here or is the usage of the Mapper just a happy coincidence in this scenario, or are you suggesting that you should always be able to map commands to domain objects?<br />ThanksAnonymoushttps://www.blogger.com/profile/03151808291682926999noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-43094260911109128492015-07-02T22:46:03.659+02:002015-07-02T22:46:03.659+02:00Nice exampleNice exampleTigerhttps://www.blogger.com/profile/12830246423865179278noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-21483520393695699952015-06-09T12:16:04.587+02:002015-06-09T12:16:04.587+02:00It's pulled out of a client project, so I coul...It's pulled out of a client project, so I couldn't I'm afraid - but the various pieces are all in the post above. Andy Butlandhttps://www.blogger.com/profile/02536557608655499040noreply@blogger.comtag:blogger.com,1999:blog-4689305754522303819.post-17863439463898598352015-06-08T20:14:59.967+02:002015-06-08T20:14:59.967+02:00Andy, could you make the source code for the whol...Andy, could you make the source code for the whole sample available?<br /><br />Thanks! Nice article.Anonymoushttps://www.blogger.com/profile/06523496536173597229noreply@blogger.com