ReviewMicrosoft N Layer App Sample, Part I
I was forwarded this link http://microsoftnlayerapp.codeplex.com/ with a request to review it. I thought about skipping it until I saw:
The main problem here?
If it is a simple business scenario, it doesn’t need DDD.
Now, just to be clear on this sample app. It is not someone working on their free time, this is something that is Official Guidance (shows up at: http://msdn.microsoft.com/es-es/architecture/en) and people are expected to read and follow this.
I haven’t reviewed the code yet, but I am scared just by looking at the architecture diagram.
Comments
Eek! That diagram looks like it was generated for a TDWTF post!
Wow that's a lot of layers for a "very simple" app....
Oh that looks like a very simple diagram. LOL
Can anyone say "mmmm - Simple"
The book has this on page 20:
DISCLAIMER: We would like to emphasize the following and remark that this proposal of "N-Layered Domain-Oriented Architecture" is not suitable for all types of applications, but appropriate only for complex business applications with a relevant volume of business logic with a long term life and evolution
They remark many times that the proposed design is only recommended for complex applications... the "sample project" is just that, a simple example of the implementation of the many patterns and design choices they recommend for a "real complex application".
Be afraid of that thing! I've made some code reviews in a company that use this architecture as a Guide not as a Guidance. This is a BAD BAD idea from microsoft's part, too many mistakes can be done using a "thing" like this.
@Michael & @Pablo, That doesn't actually work, you can't demonstrate something that is only useful for complex applications in a trivial context. If you want a sample application for DDD, you have to make a scenario where using DDD would actually make sense.
You don't use the same approach for building a tent for the weekend as you do for a 40 stories building, and trying would make it ridicilously hard and expensive. Moreover, it also completely misrepresent most of the technologies and approaches used.
I saw this in your future blog posts and had the same initial 'hmmm okay...' moment when looking at the diagram
I had a very similar reaction looking at the demo for ncqrs: http://ncqrs.org/getting-started/getting-started-with-ncqrs
I found it impossible to see the benefits because the sample was simplified to a useless degree (sending a tweet). A big part of sample applications is clearly demonstrating the problem you are trying to solve, ways it can help etc, its not just about showing off api/patterns etc.
Something completely un-related, why does your future posts say "X Day(s) from now" can it ever be, "3 days from sunday" or "5 days from yesterday"?
I find it strange.
@Ayende, your exact comment to Pablo is what I've been telling the authors since day one but it constantly falls on death ears. This is merely a sample of how to plug in as many Microsoft technologies as possible.
Wait until you open the solution, it gets better.
Slide title has typo, should be DDDD N-Layer Architecture :: Microsoft's pain...
"Review: Microsoft N Layer App Sample, part VI–Single responsibility principle is for idiots and morons - 7 days from now"
I don't know if I can wait that long.
I agree with your complains when you say it is not a real complex project. Eventhough I can say this project has been a wonderful bridge for me between the no patterns knowledge and a a more clear of what DDD means.If you see it in that way it is a great resource.
I'm using it in a project, and I reckon I'm overcoming lots of problems which do not exist at the prototype scenario. However to be honest after customizing the architecture to fit my needs I'm happy with the results and with the knowledge I'm acquiring in the process of adapting it to my scenario.
In conclusion this project is for me a worth educational tool and i that sense I think it shoul be understood
I'm scared too, it's likely they just want to showed off their tools, frameworks hheheh :)
Yes they show off their tools but at the same time the provide you a modularized architecture that allows you to change easily the technologies used without affecting your domain. For example I'm using an open source IoC framework and a different db without any traumatic problem.
I think that will a better approach to the design, presenting the same exact information could look much less complex.
You guys are totally missing the point. WHERE IS WEB FORMS!!!!?GRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
Review: Microsoft N Layer App Sample, Part IV-IoC FTW
What does FTW stand for?
JhonRed, Let me think, maybe it was the title? You can't really show those things in isolation, it doesn't work that way.
NC, What would it say, instead?
Sergio, Um, no. This is like saying that you can use an 18 wheel truck to go to the groccery store, and it has enough space in the trunk for all of your shopping. In a sense, it is true, but it is absolutely not the right tool for the job.
Alex,
FTW = For The Win
Ayende, I'm glad you're once again pointing out the problems with Microsoft's architecture guidance... but what are the alternatives? I don't see anyone else attempting to put something like this together.
I haven't been able to find any sample DDD applications that have the complexity to really show off the advantages. There are a few attempts out there, but lets be honest-- they are lacking as well.
No "architecture wizard" like yourself has any incentive to put a real DDD sample app together. It's a big undertaking with no benefit.
You're missing the point. its an Educational example, not a real world system.
From the top of the project page: <begin quote>
Project Scope This project is a sample implementation of most used patterns in Domain Oriented Architectures based on simple scenarios easy to understand (Customers, Orders, Bank Transfers, etc.).
It shows isolated scenarios useful from a patterns implementation point of view, but not necessarily as a whole business application. The architecture is decoupled and relatively complex so it would allow to grow your system.
Also, this sample goes along with our Architecture Guidance, and there are aspects in the guidance that are not covered by this sample, and viceversa.
Its main goal is to show how to use .NET 4.0 wave technologies implementing typical DDD patterns: N-Layered Architecture, Domain Entities, Aggregates, Repositories, Unit of Work, Domain Services, Application Services, DTOs, DTO-Adapters, etc. </end quote>
repositories are part of domain layer not infrastructure
I do not have the level of Ayende, of course. This is why I read this blog... to learn. But Ayende I think that in this case you are totaly wrong.
You have missing the point. This architecture is a great example. It do no pretent to be any more than an example with a guide explaining it. Every example is an abstraction an so in one or other sense imcomplete or wrong. But abstractions are usefull, are not?
I have learn lot of things about software engeenering reading the code and the guide. Sure it is not perfect but is very good. I have been able to learn lot of patterns, what DI and IoC is, which is the place of each MS technology in a DDD architecture, what is the role of unit testing in a modern architecture, etc...
I think that you are being very unfair. Have you read the guide? There are many more diagrams I think that you have just looked for the more complex one.
Maybe an 'architecture wizard' like you do not need this kind of guidance but for me the guide and the source code have been really usefull.
After learning a lot with this architecture my team decided to use it as base for a really big application and everybody in the team agree that this has been a very good decision. This architecture has demostrated to be very fexible and have very good overall performance.
Ayende I'm working on a big building, My scenario has a db with 400 tables and connected and disconnected clients. I think I would need this 18 wheel truck to avoid the chaos This project has been the most clear DDD example I've found to help me to achieve a feasible modular design.
@Ayende - Not sure, figured just 'in 5 days' would be enough. I'm not suggesting you change it, just when I read it, it's strange.
@Ayende I don't understand your attitude. The example application is only for academic purpose. All developers know what is the difference between a real application and an example application. We don't need your help for that.If you don't have something more constructive to do, please, maybe you can do better... You are a good developer, and a good comunicator, but we don't need your direct attacks against the work of others. I don't like this way.
Nice diagram! The architect should slap himself on the shoulder and everyone should be awestruck due to his brilliancy.
Please note the "Project scope" section from the sample apps main page on codeplex (http://microsoftnlayerapp.codeplex.com/):
This project is a sample implementation of most used patterns in Domain Oriented Architectures based on simple scenarios easy to understand (Customers, Orders, Bank Transfers, etc.). It is an Educational example, not a real world system, it shows educational scenarios, easy to understand useful from a patterns implementation point of view, but not necessarily as a whole business application. The architecture is decoupled and relatively complex so it would allow to grow your system. Also, this sample goes along with our Architecture Guidance, and there are aspects in the guidance that are not covered by this sample, and viceversa. Its main goal is to show how to use .NET 4.0 wave technologies implementing typical DDD patterns: N-Layered Architecture, Domain Entities, Aggregates, Repositories, Unit of Work, Domain Services, Application Services, DTOs, DTO-Adapters, etc.
Jay, Try to look at real world OSS applications, stuff that is actually being used for a purpose, not just to show off something.
Tim, You can't do it that way. You are taking something that is only useful for very high complexity scenarios and making it fit a no complexity scenario. You are showing a lot of poor judgement and not teaching anyone anything useful in the meanwhile.
I would say that if you don't have a _domain_, you can't really show Domain Driven Design. It is like trying to teach someone to appreciate music by hearing someone call out the tune sheet. The data is there, but completely out of context and utterly useless.
As for the actual code, see posts 2 - 9 about what I think about _that_.
Iker, I have 9 more posts about this sample, you can see some of their title on the sidebar right now. I can assure you that anything that you have learned from this codebase is: * Wrong * Going to be painful to maintain * Going to cost more money * Going to cost more time * Going to cost you a lot more hair
I'll leave the exact details for the posts, because there I went into more detail, but I would strongly urge you to re-consider this approach.
Sergio, 400 tables is not an indication of complexity, just of scope. And this particular 18 wheeler has different size wheels for each of its wheels, a bad steering wheel and only 1 gear (slow). It is going to be a slow and very painful ride.
Kash, It is like trying to show a proof in math, which starts with "for simplification, we assume that all numbers equal to one another". Sure, you need to simplify things to show an example, but at this point, it has been so simplified to be meaningless and actively guide you toward very bad practices.
@Ayende
This is not math...
May be you must argue about "at this point, it has been so simplified to be meaningless and actively guide you toward very bad practices"
Kash, It is a Domain Driven Design example without a Domain.
@Ayende
I don't think so. There is a domain. Yes, it's a simple domain, but I think that it's enough to understand the concepts exposed in the guide. May be you and I doesn't read the same code and the same guide. Have you read the whole guide Ayende?
Kash, Show me domain operations happening here. Show me domain logic. There is a set of entities being persisted, but they don't make up a domain
@Ayende
Domain.MainModule\BankTransferService\BankTransferDomainService.cs
public void PerformTransfer(BankAccount originAccount, BankAccount destinationAccount, decimal amount)
Kash, I would actually say that this might be the closest place for a real action in the entire code base. But it isn't a domain operation, this is a pretty low level operation, and it is missing crucial domain details. For example, try imagining looking at this transaction in a day or two. You are missing things like why it is there, what fees where charged for it, etc.
Yes, it is a sample, but the whole point of DDD is to show how complex business application behave, and not how to wrap things in recursive layers of abstractions. If they would have shown handling complexity, it would have been good, they don't.
JohnRed, Wait for parts 2 - 9, you'll be better able to understand my reaction then.
@Ayende
Like you've said, it's a sample. Leave us to exercise our abstraction aptitudes. We are enough clever to take the concept and apply it in our work.
Kash: I'm making the same general assumption by saying: No, we are not.
Ayende where is this perfect sample you are talking about? I mean, I'm not a dumb I kwow I don't hve to use this hierarchi for all my app. I will use shortcuts when I need it and I will look for more sophisticated solutions when it is not enough but that's because it is an educational project. With the time if more time is invested maybe they achieve to complete the points you mentions. But now with the things they have implementes is good enough for a really young projet. I repeat you the questeion Ayende, Where is available this perfect sample you talk about? Are you going to give me an url? I would like to download it to learn even more?
Maybe what you want is to obtain popularity complaining about this project in order to advertise your posts talking about improvements. This is not bad, at the end you are contributing to the comunity, the point is it is not fair to attack the hard work of others only because it is not complete.
The worst thing one can do with a pattern is to apply it without the context. This architectural guidance aims to answer a wrong question "What can we actually do with all that technology MS just built?" instead of "What is the most cheap/maintainable/simple way of solving particular business problems?". No business problem - no need for technology to solve it! It's not a guidance, it's a marketing bullsh*t.
The problems with samples is that they try to show a solution to complex problems (which are of necessity complex solutions) , and do so with toy, simple problems that are more easily understood. So the solution looks more complex than is needed for the problem presented - it is, but that's not the point.
As always, you need to know if the complexity will help you break down the problem that you do have, or you'll just end up with accidental complexity hindering you.
@Sergio Navarro
1) Ayende is plenty "famous" in the .NET community already 2) He was asked to review it 3) If it isn't completely, why would Microsoft put it out there?
To point 3), when will Microsoft learn that they get held to a higher standard when they put out work like this. They are the mothership, so while what they release doesn't need to be perfect, it needs to be as close to perfect as possible. Hasn't Oxite, et al taught them that yet? The fact that it hasn't is a bit disturbing.
Sergio, You may look at my github account for a lot of code that I have available. I don't know a perfect example, but I can tell you on one pretty horrible one.
Sergio, Doing so would be: * Unnecessary * Unethical
You might want to wait to see the rest of the series to figure out what is going on in here.
Anthony, Exactly! Even more, I built solutions to complex problems, so I know what good ones look like. I can't say that my solutions were _simple_, but they were an order of magnitude simpler then this.
Steve Said: 1) Ayende is plenty "famous" in the .NET community already I didn't know Ayende, sorry. I suppose he is not famous thanks to his respect for the work of others. If he didn't want popularity he would have written in the discussion forum his feedback. There a lot of the requests and complains poste are taken into account and in fact are improvements of the new release
2) He was asked to review it Ok. In a review you have to show the good and the bad things. However he shows disagree with everything and doesn't talk about the good things a lot of people have seem in this project. It is a totally biased review,
3) If it isn't completely, why would Microsoft put it out there? Do you know what codeplex is? Do you know what are iterations and look for community feedback?
To point 3), when will Microsoft learn that they get held to a higher standard when they put out work like this. They are the mothership, so while what they release doesn't need to be perfect, it needs to be as close to perfect as possible. Hasn't Oxite, et al taught them that yet? The fact that it hasn't is a bit disturbing
It is clear you don't want to understand the purpose of the project. To be perfect they would need to provide a version for each scenario. Furthermore if ir were perfect it should include a lot of complex scenarios eventhough then their will lose their truly objective that is TO TEACH
Ayende Rahien can you give me the url of your github. After reading DDD N-Layer App book.and practising with its architecture I feel I can have a bit of criteria to valuate your work. At the end of the day it seems they achieve its purpose: from VB6 spaghetti code to DDD in only a few months. It doesn't sounds bad.
Sergio,
1) If you don't know me, what are you doing on this blog? How did you got here? 2) I didn't find anything worthwhile to speak about the codebase. I think is it ugly and wrongheaded approach. 3) Do you know what shows up in MSDN is?
Sergio, http://github.com/ayende
1) Ayende, are you saying I'm lying? Incredible. I don't want to hurt your ego but it is completely true I saw a tweet referencing this post. 2) Well, in my opinion by now you don't have said nothing that supports your strong statements. We will see on your cheered future posts. 3) Yes, but if you know MSDN you see clearly that this project doesn't fit very well there, in MSDN should there are only absolutely true documentation. And this project is an evolving prototype It's natural place is Codeplex.
Thanks for the github url, I'm very impressed by the projects you have hosted there. The point is these projects doesn't means you are always right in all your valuations specially at this topic just because you arem't being able to put in the place of an unexperienced programmer/architect who needs this kind of simple and at the same time modulated samples to learn. When I have more time I will check the samples you have there. Thank you
Which part of KISS did you or did you not understand LOL
@Sergio: out of curiosity can I ask: have you read the Eric Evans book that basically defines what Domain Driven Design is? The sub-title of the book is "Tackling Complexity in the Heart of Software". The point is that the patterns in the book are only applicable when you have a complex domain as their intent is to help you manage that complexity. So how can a sample demonstrate the benefits of DDD patterns when it has none of that complexity? In fact, how do you even know if the sample is a good implementation of those patterns? An implementation can only be good if it demonstrably solves problems arising out of a complex domain, right?
If you're truly interested in learning about software architecture then can I suggest that you could do worse than listen to what Ayende has to say on the subject. Dismissing what he has to say just because he's being critical isn't the way to learn anything.
Cheers.
@Sergio,
Against my better judgement I'm responding to you.
1) Yes, Ayende is not famous due to respect he has either paid or not paid to other peoples work. I guess you're asking why he didn't post his comments to the codeplex forum posts? Well, he has written 10 posts on the subject with images, not really something the codeplex comment engine could handle
2) In a review, there is no rule to show the "good and the bad things", a review is a critique, that is all. Not sure why he is "biased", it's not like he has his own DDD sample out there, again he was asked to review the application. Not sure why that isn't clear by now.
3) I know exactly what CodePlex is, but when something comes from Microsoft, it better be held to a higher standard than something I can hack up over a weekend. Sorry, them's the breaks, Microsoft continues to fall flat on their face when it comes to these sort of things, then they act all hurt and surprised when it happens.
Whether you think it should or not, this code WILL be held up by developers all over the world as the way to do DDD. Inexperienced (or lazy) developers go to these sites and copy and paste like crazy. It wouldn't surprise me if this code is already being added to real world projects. This happens all the time, from the sh!tty Oxite project, to the thousands of poorly written MSDN samples, if it comes from Redmond it is treated as gospel by a very large portion of the .NET community. They don't say "well, maybe this is Microsoft's first crack at it, maybe I'll not look at it for guidance, even though it's labelled as guidance."
Rob Conery did an overview of this app too: http://wekeroad.com/post/7102729511/a-simple-example-thats-incredibly-complex
I have read the guide and my point of view and I agree that this N-Layer DDD Architecture Guide is not necessary in RAD projects and small apps architecture.
However, this guide is 100% valid for complex applications with large volume of business rules and a long life cycle management.
I think we should keep in mind that this guide and sample application are designed to show how implement Domain-Oriented patterns using .NET, Repositories, UoW, IoC, Entities/Aggregates, Domain Services, etc.
I agree with the comments of Tim Cromarty when he says "its an Educational example, not a real world system".
Regards.
Sntimacnet, DDD is not a concept that is about repositories and UoW! It is an approach for software design, not a set of coding patterns that you blindly follow.
I'm one of those maybe LOL idiots who has copied and pasted the project, thanks guys for your disqualifying adjectives. I did it this some months ago and now the project is different from the original. I have detected bottlenecks that doesn't fit with my scenario and also improvements. However I have also found some overengineering sollutions proposed in the project (due to it is used for a very simple domain) that are perfect for my solution. The best was I dind't need to undesrstand any complex scenario to undestand the purpose of this solutions just because when I used them on my domain was easy to know if they fit on it or not.
An example: Ayende in one of his posts say the following regarding the the IoC abstraction. "Yes, they abstracted the Inversion of Control Container. I think that if you need to do that, it is pretty clear that you don’t really get what IoC is all about." Not many reasons within your words, the idiots as my won't be able to catch it. I suppose you mean is useless an abstraction because it doesn't allows you to use all the features of an specific IoC framework. Yes that's right, but as all of us know that because we have read DDD gurus books, this is the disadvantage of using an abstraction of an specific technology, the advantage is to be ready for the change of IoC framework.. In fact for my project it helped to me to change easily in the middle of the work to a different IoC which offer features that fit better with my scenario and that is compatible with more platforms. To be honest I needed some extra methods in my IoC abstraction for allowing an architecture of distributed modules for registering the IoC mappings and lifecycle control but this changes dind't affected a line in the domain code I had written. The idea is to have an abstraction that cover the features you need from an IoC framework. In fact if you change to another IoC you will do it because it offer the same feature an more, so you will need to add but not modify the abstraction, this comment is also valid for the Aende's post about the ILogger abstraction in the project. The point here is that if Ayende were the author of DDD-Nlayered Architecture project he would have discarded the use of an abstraction for IoC. Thus, me as a learner would have lost the possibility of taking this decision because he took it for me and I will have lost this opportunity to learn.
I conclusion, what we have here is two different but reasoned points of view. What I cannot see is any reason for maiking a review in those disqualifyng strong terms.
Sergio, I am not really sure where to start answering you. I have a lot of posts about IoC that you might want to read up on: http://ayende.com/blog/tags/ioc
Put simply, IoC is about inversion of control, about "don't call us, we'll call you". If you are explicitly calling the IoC container anywhere except very deep in your infrastructure, you are doing it wrong. For example, in an MVC application, the only place where the IoC is exposed is in the controller factory, never anywhere else.
If you do it right, you don't have to worry about abstracting it, because there is no one using it!
Jumbo Shrimp
I threw up in my mouth a little when I looked at the solution. ZOMG. Abstraction on top of abstraction wrapped in abstraction surrounded by a little abstraction.
Ugh. I need a shower.
I believe that in NLayerApp the only place where they call to the container is within WCF Services methods (and MVC controllers in V1.0), not everywhere, like I think you say, except within the Unit Tests, when testing every layer independently. In fact, they do as you say, calling the Unity IoC container only from the app-server entry points (WCF or MVC) and then starting the DI object graphs from there, using dependencies based on constructors down to the last layer. Regarding the topic about abstracting the container, they already changed that on the V2.0 in spite of that I prefer to use an abstraction. Maybe at the beginning you need to take a shower XD but now I'm totally used to it and avoids me any change in all the unit tests when I call the IoC Framework. You can argue that maybe is too much to use IoC in Unit-Tests. Personally I prefer it in order to check the lifecycle mechanism and mappings I have coded.
Sergio, MVC Controllers, WCF services, as I said, everywhere. You don't call IoC from places that run code that you usually touch. You get one location in the application to call the container, other than that, it is forbidden.
So they've reinvented Java?
I understand, you agree with the factory but you don't like the extra abstraction for the container when its code can be simply within the factory. Yes you're right, but it doesn't makes a big difference on the sample architecture. In fact originally when I was even more ignorant than now, when I saw it for first time It reinforced on me the idea that this project had Microsoft technologies but I could change it in a very easy way. I don't think it is a big sin.
@Sergio take some time and read this article thoroughly: http://bit.ly/a7lU76
@Arnis, the sample of the article you reference is an antipattern because the call to the IoC framework is done within a Domain Entity. In N-Layered Domain-Oriented Architecture you cannot find anything like this. The calls to IoC Framework are done only on entry-points of the app. The thing is that I think that Ayende says that at this entry.points the resolve call should be resolved directly by the factory instead of having to call to the factory to obtain the abstraction of the IoC who will resolve our request. Ok that's right you avoid one step and make it more simple, but id doesn't change nothing on the architecture. The project didn't use any antipattern neither before this change nor after.
@Sergio
-"In N-Layered Domain-Oriented Architecture you cannot find anything like this"
take a look at ayende`s "part-iv-ioc-ftw" http://bit.ly/o3NnLM it's not about calling IoC directly from domain entity, it's about calling IoC directly in general. normally you want to use constructor injection.
2nd thing is about abstracting IoC itself (IoCFactory class). it makes no sense unless you are building re-usable framework. that isn't the case.
argument that "you will be able to switch container lately to another one" is weak because there should be 1 place only where you talk to container - at so called composition root (application entry point, in mvc it's usually controller factory). therefore - creation of an abstraction just to abstract away one method call is yet another overkill.
I really wished you had approached this from a different angle If you did not like the code in this book than please just show me other books and articles that can benefit me. I personally love the thought of domain development and yes prism and unity. I really believe when you are talking about ddd than that's when disagreements always start. I do applaud microsoft for at least starting to put something down to try to help the developer. Ayende, Please realize I believe it is never too late to learn. That's why, I challenge developers who truly care and want to help people to write books(dont tell me it cant be done,People have climbed mountains so yes getting a book published can be done) At the very least top developers can write ddd .net code to help people over the internet. So yes If something makes you upset than it's up to you to give feedback to microsoft or write your own code to improve it.
I don't suppose you actually opened the guide, which in fact states when you should NOT use this approach?
Comment preview