Clean Architecture Example & Breakdown - Do I use it?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody it's derek martin from codopinion.com a lot of people have asked me directly or indirectly about the clean architecture in my opinion some people have asked me directly and pointed out to jason taylor's c-sharp template while others have asked me indirectly because of the code samples that i have in some of my other videos where i don't apply it so here's my opinion and thoughts on clean architecture templates where i see the value and where i don't so let's cover the clean architecture really quick and just describe this diagram which you've probably seen this is from robert martin's blog in 2012. the very middle is essentially the core is our domain this is where our business rules are outside of that our use cases these are our application how it's invoking those actual domain objects those entities then you have things like controllers if you're doing something like mvc or gateways or presenters for ui but again this is one step further where this is what's actually interacting with calling those use cases and above that is all things external so if you're generally creating a web app this is where the web host is going to live if you're creating a native ui app this is where that ui framework lives but the key thing here are these arrows and these arrows are really pointing inwards that's why i have dependencies point inwards because that's really the key to all of this is that outside layers can reference inside layers but inside layers don't reference outside layers so if you watch my video on coupling specifically talking about afferent and efferent coupling so afrocoupling being who do you depend on in effort coupling being who depends on you is why this is important is because that the very big at the very center here with our domain and our entities who depends on you for afferent coupling well the use cases does who do you depend on efferent coupling nobody nothing is that you don't depend on anything you have no dependencies within entities and as you go out that starts reversing so a lot of this to me and about clean architecture is about dependencies and having that core have no dependencies things depend on it but it does not depend on anything else so a lot of people pointed me to this specific template this is the c-sharp template clean architecture by jason taylor so this is going to what i'm going to use as my example so this is what the actual solution looks like there's four projects application domain infrastructure and web ui so what that looks like from the diagram is the outside here web ui is asp.net core it references infrastructure and application infrastructure is the project that contains like the db context for nad framework and any implementations of any services the application is handlers in commands and queries that's using mediator and then it is referencing the domain and the domain is our entity framework entities so first let's talk about templates for a little bit because i have a love hate relationship with templates and because it falls into the only issues i have with my own code which is providing examples that are simple that people can understand and hopefully the concepts behind it so that they just don't run away with it and keep doing the same thing that they understand their context to see if it actually fits that's the problem i have with templates is that this is a to do list kind of to do item sample that it's using to illustrate this which is super simplistic and exactly i understand this is a template it's an example that's why it is simple but the problem is again people going with this and running wild with this when if you're creating a a smaller type of application do i think you need to do clean architecture no i'll explain why more shortly but i don't think you need to so depending on the size of your app i think there's benefits um to the clean architecture i also think there's a time and a place for it depending on the complexity and the size of your app so what i'm gonna do is go through this template and i'm not criticizing the template so much as i am just trying to explain what i think actually belongs in each project if you have that project again it's this is a template it's a sample so i don't expect it to have a ton of complexity to illustrate really the nuance of why you want clean architecture so the first thing i looked at when i opened this project was this domain project and this is the very center of the core it has no dependencies so it preferences no other projects and when i was looking at it i wanted to see what the if there was if it was doing some aggregates if it had entities whatever the case may be and ultimately what it was is it has this to do item and to-do list which basically are our entity framework entities there's basically no behavior on here at all why would you expect there to be any it's a to do but that's the part where it gets lost is again if people are using this as a template they think oh this is where my entity framework entities go and while it's true that you can have your entity framework entities live in the domain project you can have the infrastructure project which i'll show here has the db context the entity framework db context and it's referencing it and it's using them i would expect my domain project to actually have business rules and again this is a simple example so there are no business rules but my domain project is the core of what my application is it should be the one containing all the business rules this example template displays none of that it illustrates none of that so if you weren't aware of that's the point of the domain in your entities and if you're creating something like aggregates that are consistency boundary check out my video on that that's where this would live but just looking at this template you wouldn't know that all right so the next thing to look at is the application project so this is the one that's referencing the domain so it's a layer above the domain so the things that it has in it that are somewhat interesting i guess in what i like about having kind of this application layer is it's the one that's actually going to invoke and call stuff within your domain so there's this to do items folder and to to-do list folder and it has everything separated for commands queries and event handlers now i'll talk a little bit more about this technical separation later on how i prefer it but i do overall like this approach as you maybe have seen in some of my other videos but one thing i really find interesting is that the application uh this particular project is going to define interfaces just interfaces not the implementation for things that it needs one of those things it needs as you can expect is a entity framework context so instead of referencing the actual db context that's being used directly rather what it interacts with and uses is this eye application db context so the reason why i find this interesting and why i don't generally follow this approach is because of a leaky abstraction and this is showing it whether you realize it or not yet right now so the infrastructure project is what implements all the interfaces defined in the application uh the application project so if i look at infrastructure i go down there is a persistence and application db context so here's our actual entity framework uh db context that we're using and it implements that interface so when i look at that interface the idea here on the application is it is kind of lost on persistence it doesn't really know how it does it doesn't necessarily know that it's entity framework right we just have these lists well actually it does know it's entity framework because it's using these db sets and these db sets are directly coming from entity framework actually this application project has a reference to entity framework so i'll ask you the question if you're going to have a leaky abstraction or you try to want to ignore what your persistence is you're not really doing it with this approach especially how this is anyways so you may be screaming well use the repository pattern i'll save that for another video because that's a whole different topic so i'm all for abstractions the right abstractions and most times i think external services i think are really good to abstract because you can kind of narrow the focus of what that abstraction does and what you need it for but when you're doing something like entity framework or data persistence i think you lose a lot and i generally don't think you actually need it i say that because if you're creating small applications like this or smaller little components which i'll talk about in a minute you don't actually need the abstraction because the actual cost of rewriting where that data access is is so low it wouldn't really even matter you don't even need the abstraction and secondly if you're gonna actually create an abstraction what are you losing by using the direct client or sdk that you're interacting with if you don't have a really narrow focus and you need to use a lot of it then you're just trading more and more into your abstraction to fit it if it's something really critical to you just use it there are exceptions to the rule i mentioned this in other videos messaging libraries give you a lot of functionality that you otherwise wouldn't get from the client or sdk directly that you have to implement yourself so those are the type of distractions that you do want but you're not creating them you don't own them you're using messaging libraries for this all right so the last project to look at is the web ui project so this is the very outer edge this is asp.net core and we have some controllers in here as you might expect so let me jump into the to do items controller and you can see that it has some various actions for kind of crud related things um that we need to interact with for our to-do item now the reason why i don't actually like controllers in general is because they have really low cohesion and especially even more is that um all these particular commands here this create create to do item command this is exactly a one-to-one like this particular action in this controller maps directly to the command and command handler this is the only place at all in solution besides tess that this is actually ever created there's no other place that's creating a to do item there's no other place that's invoking it anywhere calling send on it it's simply here so the reason why i don't like this is because i much prefer having things close together i don't want to have to jump through projects and files i would much rather see everything that belongs together is together and i can go into one location and look at basically everything so when i say group things together i'm generally less concerned about layers for an entire application and more thinking about features and functionality and kind of the concerns within that feature so i'm less concerned about abstractions and i'm more concerned about just what a feature does and letting it define its dependencies and whether it needs an abstraction or not so instead of thinking about the whole layers i'm thinking about what's a particular subset of features and let's pull out the important parts and put all that stuff together so well instead what it really looks like is maybe i have two web ui pieces which are really the controllers that's interacting with say the same infrastructure which maybe could be the certain db context which interacts with our app which is our mediator commands or queries and handlers and maybe those two particular features share a domain but i'm organizing code that way i'm not organizing code necessarily by layers that's happening in that template so taking that concept and consolidating it what this means is i have two projects now not four i have the outermost which is the web ui which is asp.net core and i have to define this as kind of the entry point this could be asp.net core this could be a native ui this could be like a service that's interacting with your your message broker that's going to be invoking into your application this is kind of topmost entry points but i don't actually have any of the controllers here really the controllers are living in their respective features so i now have a folder called features and i have these to-do list items and lists and items and instead of having a file for basically commands and queries like it was earlier and event handlers i left the event handlers in here because they don't really do anything normally these would actually just be a part of this name to what they actually do but if i jump into the create to do item here it has the controller here the web ui is referencing this it's automatically going to pick up this controller i have the relevant mediator command the validator for it and the relevant command handler since it's publishing an event i actually have the event here as well so when i'm talking about or thinking about anything to do with an actual command everything resides in one file it's one place now often the argument is well now you're referencing asp.net core in this application project but it really only needs to be in the web ui true that is true however if you do create some other service if you do that doesn't need asp.net core well yes you will still be referencing it and it just won't do anything that's a price i'm willing to pay to have code that belongs together live together so that i can access it directly and understand instead of jumping through projects and layers i have things closer together so you'll notice i took out that domain project and the reason is is because there was nothing meaningful in it if i was creating a rich domain i did have a lot of complexity around my domain and i wanted to create a separate project so i didn't have any other dependencies that i could focus specifically on that domain to create entities values objects aggregates then yeah that'd be a great idea in this example for illustration purposes there wasn't anything meaningful in it so therefore what's the value of having that project so the value to me in separating by project is if you want a hard physical boundary with dependencies an example of this is that you don't want to accidentally put say some type from asp.net core in a mediator command or query because if you do need to rip that out well now you are actually bound to asp.net core because you have that reference in there in the original template you wouldn't be able to do that so again yes it is about context it is understanding what you're doing and what types you're using where if you want to accomplish that by having the boundaries of projects and layers excellent that more power to you if you can see past that and you actually want to create slices where you're depending less on abstractions and creating smaller units where you can refactor those and pull those out separately then to me there's less of a concern about those abstractions because if you need to replace them what the actual underlying implementation is with something else you can do it so for everybody that's been asking me about this i hope it helps if you found this video helpful give it a thumbs up if you have any thoughts or questions make sure to leave a comment and please subscribe for more videos on software architecture and design thanks you
Info
Channel: CodeOpinion
Views: 170,113
Rating: undefined out of 5
Keywords: clean architecture example, software architecture, software design, cqrs, event sourcing, design patterns, software architect, .net, soa, microservices, message queues, kafka, event bus, event driven architecture, rabbitmq, service bus, message queue, message queuing, messaging patterns, service oriented architecture, microservice architecture, domain-driven design, enterprise service bus, clean archetecture example, clean archetecture exemple, Clean architecture exemple
Id: Ys_W6MyWOCw
Channel Id: undefined
Length: 15min 24sec (924 seconds)
Published: Wed Jun 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.