REFACTORING to MEDIATOR & CQS Pattern | AWS Lambda | ASP NET Core

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
refactoring is the process of changing existing code without changing its external behavior or functionality refactoring is intended to improve the design structure and maintainability of the code while preserving its functionality it is not a one-time process but an ongoing activity that the team needs to embrace in this video let's look at an example of how you can refactor an application into a much more maintainable structure i will mainly be using two patterns to which i will be refactoring i will be using an aws serverless application template to do this but the refactorings applied are applicable to any application it's very much same if you are building an asp.net core application or a dotnet console application or any application using the.net ecosystem hello everyone my name is rahul and welcome back to my youtube channel here i usually talk about dotnet cloud and devops please hit the subscribe button and help me grow this channel without much delay let's head off to visual studio and create a new application from a template we will be then refactoring this application template into a different structure that's more maintainable and easier to understand so let's click new project and search for aws serverless let's choose the aws serverless application with testunder.net core as the option and click next let's name this application as my application dot host i will come on to why i have named host in a short while let's keep the solution name as my application so let's click create this is going to give us an option to select the type of application that we want to create in this particular case i will be using a blog api using dynamodb this simulates a real-life situation where we have an api which talks to a real database in this case this is dynamodb in your application this could be different you could be talking to sql or any other nosql database and this could also be an asp.net web api application where there would be a controller and instead of that here we have functions.class so let's use this and move on to create the application the application is successfully created so we have the my application.host project and also the myapplication.solution file now to give a quick overview since this is an aws serverless project the entry point is dynamically done by the aws host so all we need is the functions.cs or this template which links it to the particular functions that we want to host in aws let's not go into much details about this because the intent of this video is not that now if you want to learn more about aws lambda and how it works you can check out the video that's linked here or in the description below so let's go to the functions.cs class which is the main class in this particular application this is very similar to a controller class if you are building an asp.net core web api application so let's scroll down and here we can see this uses an i dynamodb context which is the context that's required to talk to dynamodb so we have the main constructor where we set up a lot of the things for this particular class so here we also set up the dynamodb context so let's collapse all these functions and we can see there are different functions in this class to get blogs to get a blog add a blog and remove a blog a usual crud create read update and delete kind of style api but if you see in this particular function there is a lot of things going on if we expand one of the functions let's say get blog sync we interact with the i lambda context get out parameters from that so we are interacting with the aws infrastructure and then we make some code for our domain and also interact with the database so there is a lot of things going on in this single class since this is a small application currently it's easier to maintain however as the application grows such kind of function classes becomes hard to maintain so let's see how we can refactor this into a more maintainable and easier to discover application if you've seen my layering video earlier i had introduced you to the onion architecture now this is one of the styles that i have commonly used across my applications in the past and it has always worked well it makes the application easier to maintain discover and also add functionalities to it so if you are building a small to a medium sized application i highly recommend checking this out in that video i had created two other projects mainly for the domain and also to handle the infrastructure so let's see how we can create the same in this application so let's open the solution explorer and add two more projects so let's right click and say add new project and call it my application dot domain we'll keep them as class libraries because that's not going to be hosted by itself so let's click class library and next in this case we will name it my application dot domain and click create let's also create one more project using the same process so let's click add project and select class library and name this my application dot infrastructure we don't need this extra class cs so let's delete that which is automatically getting created and also delete the one that is created by this infrastructure class let's also add in the project dependencies let's add the appropriate project dependencies for these multiple projects the host application needs access to both the assemblies because that is hosting the whole application so let's add domain and infrastructure to that the host is also where we compose the whole application so that contains the composition root now the composition root is the entry point of your application now this could be an aws serverless application like in this case or it can be an asp.net core web api or a mobile phone application host or anything that is hosting your application usually the dependency injection and the registration of all the services happens in this composition route this is the reason why it needs access to all the dlls that's part of this application because it needs to compose the entire application in that route so let's make sure to add the references to the other two assemblies so let's right click on dependencies and say add project reference we can select the domain and the infrastructure projects in this case and click ok now the domain project does not depend on anything so every other project actually depends on the domain project this is why it forms an onion architecture it peels out from the outer layers and starts depending to the core which is the domain so let's now add a dependency to the infrastructure and add the project reference and select domain in this case so anything that the domain needs will be added as interfaces in the domain class which will be implemented by these outer layer projects which in this case is in the infrastructure so if we need to access a repository let's say for example we will have an interface within the domain project that will be implemented by the infrastructure we will soon see how that's working now that we have the projects added let's build this to make sure it's all working fine the build is working fine so let's open the git changes dialog and create a git repository and make a comment now by creating the repository from within visual studio it has automatically committed all the changes that was existingly there to verify that let's go to the bottom right where we have the branch that's the master and then select view history now we already have these two comments automatically happening because visual studio chose to now let's start refactoring this application along the way we will make proper comments so that you can review this in case you want to let's first go to the blog.cs class this currently acts as a data transfer object which is just transferring data to the external api but as you build your application this might have more features and might more act like an entity now i had touched upon what the differences on entities and value objects are in my video on layering so let's move this blog.cs into the domain project because that is a domain concept so let's click and drag into the domain class we can move this into an entities folder to do that right click add a new folder and name this entities and we can also move this further inside that now to make sure that the name spacing is correct let's open up theblog.cs and make sure the namespace is correct as well so let's say change the namespace to domain.entities and let's save this class now we also have the old file existing here which we will delete in a moment later coming back to our functions.cs class let's start seeing how we can refactor this particular class now as we saw there's a lot of things that is happening here which is interacting with various kind of infrastructure the aws serverless host the dynamodb and also it has a bit of domain logic now the easiest thing that could come to your mind is to make a service class or a manager class or a class which is similar to that which can manage a blog object in this particular case now i have seen this kind of a pattern across in different applications now these classes usually start out small with a get create update and read functions but as the application grows it becomes larger and larger now these classes could also end up becoming a dumping ground let's say for example you have a user and a list of blogs and if you want to get all the blogs for a user would you put this under the blog service class or would you put this under the user service class now this often is confusing and then you would end up dumping it in one of them or even creating a user blog service class now these classes often tend to become like god like classes which has a lot of functionality inside that now it need not be named as service or manager it could be anything the easiest way to identify it is open up any class in your existing source code and see if it has more than four to five constructor parameters if this is the case it's very likely that this is more like becoming a god-like class which has a lot of functionality and hard to refactor and change so let's not use the manager or service kind of classes in this particular application let's see two patterns that helps us solve this problem this is the mediator pattern and the cqs principle which is command and query separation let's see this in detail mediator is a behavioral design pattern and it reduces the dependencies between the objects so there is a mediator in between through which you interact with other objects with this pattern it restricts direct communications between objects and forces them to go via the mediator object with command and query separation the fundamental idea is that you would divide an object's methods into commands and queries a query is anything that reads the data and does not change existing data so it does not have any side effects whereas a command is something that updates or deletes or modifies an existing data so it does cause a side effect if you look at the create read update delete set of accesses usually the create update and delete falls under command and the read is usually a query so with the cqs principle we separate the commands and queries as separate actions or tasks within our code let's see how we can use these two patterns in our application to implement the mediator pattern in dotnet we have a library that's quite popular which is called mediator now if you scroll down you can see this is a simple mediator implementation in dotnet this is an in-memory implementation so it's quite easy and fast to set up and get started with so let's use this in our application switching back to visual studio let's open up the solution explorer and right click on the solution and say manage nuget packages for the solution let's choose browse and search for mediator now by managing the packages for the solution we are able to add packages to multiple projects at the same time so let's choose mediator which is the library that we just saw and install this in the domain and also the host project and let's click install with the package successfully installed let's navigate to the functions.cs class and start using it now to start with let's create an instance of this within the class variable so let's use i mediator which is an interface that's provided by the mediate and you get package and name a mediator property let's keep this a private or you can even keep this read-only depending on the pattern that you use in your application so let's leave it as private for now we will see how to instantiate this in a moment later but let's start using the mediator pattern within our functions so let's modify the get blocks async method which is the simplest in this case which gets all the blogs from the dynamodb database now currently what it does is it calls a db context it uses the scan function which is basically like getting all the blogs within that db context and then it returns back to the user let's modify this to use the mediator pattern to start with let's comment this code which interacts with the db context and replace it to use the one with mediator now if you use the mediator class you can see it has lots of methods on this the one that is of interest for now is the send method this helps us to send command and queries to this particular mediator now any of the functionalities that's associated with the queries or commands gets invoked in that case now in this particular case what we need is a get blogs query so let's go back to our domain and start adding the queries now the queries and commands are a domain concept because it's related with the domain which is why we are adding these commands and queries within the domain project to keep them separate let's add folders again so under the domain let's create a new folder which is called queries let's create a new class under that and call this get blogs query let's make sure this is public to make this as a mediator query and the one that can be used within the send method i need to make this implement i request interface so let's add in that interface and make sure to use the correct name space now this interface is a generic interface and it takes in the response type as well now in our case since the functions.cs is returning a list of blocks let's return an i enumerable of blog so let's use i enumerable and specify the blog class which is coming from the domain entities so let's make sure to appropriate usings and click save now since in this particular case this query does not have any parameters we can leave this blank but if you are getting the blocks for a particular user then you can add a property for user id in this particular query class we will see that in the next example to implement this query that is to have a handler we need to create a handler class so let's copy this class name and create the handler in the same class for now if you prefer to keep them separate you can do that as well so let's add a public class get blogs query attach it with a handler because that's handling that particular query now to have it associated with mediator we need to implement the irequest handler interface which now takes in the type of the request in this case this is the get blocks query because that is the query that this handler is handling we also need to specify the response type which is now going to be i enumerable of blog because that is what it returns back so let's implement this interface so i'm choosing the implement interface and then it automatically implements a handle method let's see how we can implement the handle method now so this takes in a get blocks query request and a cancellation token which will be passed in from the calling code to interact with the dynamodb database we need a repository interface because that is what is going to talk to the dynamodb now as we saw in the layering video we inversed the dependencies and we made the interfaces belong to the calling client so in this case since it's the domain that needs to access a repository let's define the interface closest to it which is inside the domain class so let's add a new interface inside here so let's create a new item choose interface and call this i repository let's make sure to keep this public and also add in a generic type because this can be for any repository so for now let's add a simple method which returns a task of i enumerable of the type t which will be replaced to block by the calling application and define the function as get all now it doesn't need any parameters in this case so let's leave it blank let's make sure to add the appropriate usings and we have the interface defined now i can start using this repository within our query handler so let's switch back to get blogs query and inside the constructor let's inject an i repository now since i am dealing with blocks i need an i repository of block since this is generic we can give it any class that we want let's call this blog repository let's make sure to create a backing variable for this so let's create and assign a field blog repository so it automatically sets this inside the class to start using the blog repository let's change this not implemented and return the blog repository dot get all method so this simply proxies through to the repository in this particular case as your application grows you might have more logic inside your domain and you will be adding that inside this class now one thing to note here is that i am using the blog entity itself as the return for this query class now this is because i need all the properties back to the api now if you only need a subset of these properties let's say this is a page where i just want to show the id name and the date and i'm not worried about the content then i can create a new class that maps to this so in this case what will happen is you will have a get blocks query and you can also have a get blogs query response and use that as the response type you will be doing the appropriate mapping inside your repository class since in this refactoring example i intend to keep the behavior the same i am not doing that now that we have the query and the handler created let's go back to the functions.cs class and start using this query class so let's call the mediator.send call in the new blog query method so let's create a new instance of that and call that in here let's make sure to add the appropriate usings let's add the closing brackets and the semicolon now we can add the variable blocks and await on this call now this is going to return back an ienumerable of blocks which is what the query handler is doing once we have the blogs we can start using this inside here since this is a i enumerable let's use the count function on that let's also return the blogs in this particular case insert of the pages with that setup let's go into the infrastructure project and start implementing the repository that we just created so let's go to the infrastructure create a new class let's call this dynamodb repository because this is a repository that deals with dynamo database so let's call that appropriately let's make sure to make this public and then implement the interface i repository of t since this has a generic type inside the interface let's also make the repository implementation as generic so this can implement for any type let's implement this interface which asks us for the get all method now if we come back to the functions.cs we saw that we use the dynamodb context and used the scan async method so let's copy up the dynamodb context and start using that inside the repository so we will inject that into the constructor of the dynamodb repository now let's add in the appropriate packages into this infrastructure project that can talk with dynamodb so let's use the version that's already installed in this project in the host project with the nuget package installed let's call this the dynamodb context and add a field to this class with this specified we can start using this inside the get all method so let's return call the await and on the dynamodb context we can call the scan sync give the type of the t because that's what we are acting upon and then call the get next set async this is exactly the same that's happening in the functions.cs it's first calling the scan async it's passing in a null and then calling the get next set async so let's come back make sure to pass a null to the scan sync and return back the result from this particular class let's also add in nsync to make this to compile i usually prefer to keep the calls to subsequent functions in link on different lines so let's format it accordingly now this allows us to keep to the left aligned which is more easier to read for me but your preferences might be different let's save this class with that setup let's now start wiring up all these different classes and interfaces that we have added inside the host application now if you are building an asp.net core application this is going to be under the startup class and in your configure services method which is where we wire up the dependencies now if you're new to dependency injection in general with asp.net core i highly recommend checking out my video which will be linked here and in the description below since the startup.cs class does not exist inside here we can create a similar class inside the host project so navigating to the host let's create a startup.cs class inside here you could name this any way you want like bootstrap or anything that you prefer i'm just keeping it startup so that it's very similar to asp.net as well let's make this a public static in this particular case since we don't need an instance of this class let's add a new method we can name it configure services or init or anything as you prefer so let's return a void for now and call this configure services let's make sure to mark this as static because the class is static to start configuring the services we need a service collection so let's create a service collection instance and call in the new service collection now this could be any other independency injection container like if you want to use auto fact you can use that as well but in this case i will stick with the natively available asp.net core dependency injection provider so let's use the microsoft extension dependency injection package and install that into this project with that installed we have this instance created let's first register the mediator related classes into the service collection now to do that the mediator provides a new get package that can easily integrate with the service collection class that we just created so it's called the mediator.extensions.microsoft.dependency injection so let's copy this and go to our host project and add this as a reference so let's go into host dependencies manage new kit packages and browse for that package that we just copied let's add this to this current project come back to our startup class we can add the using mediator namespace and start using functions from that if we navigate back to the web page we can see how to use this if we just want to specify one handler we can add the type of that handler or if you want to add all handlers and the queries inside an assembly you can use the assembly registration format in our case let's use the assembly format that makes it easier so let's copy this line switch back to our startup class and call this on the services collection instance that we just created now this calls the add mediator functionality and then specifies the assembly that it requires since all our queries commands and handlers going to be part of the domain assembly let's use a class from the domain assembly so let's copy the get blocks query class navigate back and use that instead of startup let's make sure to add the appropriate usings and this gets the type info using the reflection and specifies the assembly here now this registers all the commands and handlers and the queries that we might add in the future to this particular assembly if you have them in different assemblies you can register that here as well with that specified let's now register the repository class that we created to do that let's call the add transient method on the service collection specify the type of the interface now since this is an open generic i need to use the type of rather than using the generic method on the transient function so let's specify i repository of t so i can specify it as an open generic make sure to add the appropriate usings and specify the implementing type in this case that is going to be the dynamodb repository and again with the open generics now let's add in the appropriate usings as well and make sure we use the appropriate class name the only thing that's remaining is the dynamodb context if we go back to the functions.cs class we can see how this is set up inside the constructor so if we scroll up and expand the functions this is using the dynamodb context and specifying an i dynamodb client so let's do the same to get this connected inside our class now the template also uses a table name variable which it determines to find the table name if the environment variable doesn't exist it just uses the class's name as the table name which will be blog in this particular case so let's copy all this inside our startup class and use that inside of there so let's remove this from here and paste it inside the startup.cs if you want we can create a new function let's say register dynamodb and keep that inside that particular function so let's also pass in the service collection in this particular case so let's create this new method inside this class itself now we can paste in the copied code and start registering the dynamodb inside of that so we need the table environment variable which is also there inside the functions.cs so if we scroll up we can see this constant being used so let's copy this comment and paste that inside the startup.cs class as well this needs a few using statements so make sure to add them and instead of assigning it to the db context let's add this db context to the service collection so let's get this as a temporary variable and use that to register inside the service collection it says service collection dot add singleton because that's how the dynamodb context needs to be registered specify the i dynamodb context which is the class that we injected in into our repository so if we go to dynamo class we can see there is the i dynamodb context so let's switch back to startup and inject in the instance for that which is db context now in this particular registration it expects this application to run in the aws infrastructure so that it can talk directly to the dynamodb instance on it which is why we don't see any connection string or user credentials getting passed now since i want to be able to run this on my local i will set this up to do that since this is of not much focus for this video i will simply copy paste that code and not go into the details of that if you want to know about it and dynamodb in general you can check out my video linked here or in the description below so let's copy and paste a few config that i have already created which is a credential and specifying a basic credential which i had created from the aws portal it is using a client id and a secret to access that once this is specified i can use this when i create the amazon dynamodb client so i can pass the credentials and also the dynamodb config that i have created so let's use the db config here so this is going to use this credentials and this region to connect to the dynamodb instance now once that is set up we have everything set up for our application we need to start using this startup class inside of our functions class so let's save this go back to our functions.cs and inside our constructor let's set up the mediator instance so let's make sure to remove this additional space in here we can say this dot mediator is equal to we can use the startup class configure services and resolve a mediator instance from there now since the configure services currently does not return anything let's make this to return the service collection so let's return the service collection and also let's make sure to build the service provider before we return this so we are returning a build service provider this might differ depending on the dependency injection container that you use now this is going to return an i service provider instance so let's change this void and make this iservice provider with that let's go back to the functions class and resolve the instances from here so here we can say this is the service provider dot get service and we can use the generics and specify imediator to get this to work let's make sure to add the appropriate using statements so let's call microsoft dot extensions dot dependency injection in this particular case and this now compiles so we are creating the builder and getting a service explicitly inside our functions class if you are doing this in asp.net core this will be automatically done by the startup class and the configure services method now that we have the mediator instance resolved this will be working when the get blocks async method is called so we can safely remove these two commanded code in this case now let's build this and run to see if it's working so let's keep a break point here build the application the build is successful so running this application is now going to launch a lambda test tool which can be used to test serverless applications in localhost now if this is an asp.net core web api it would have automatically launched it inside a browser the experience is very similar in lambda as well now this is the test tool so it allows us to call the different functions inside that test tool so since we want to call the get blocks let's make a request to the get blocks endpoint if we switch back to our code you can see this is expecting an api gateway request so let's make an api gateway request so scrolling to api gateway proxy we can use this to make a call so let's call the execute function this hits the breakpoint as expected it's going to send the get blocks query so let's navigate to the get blocks query and make sure to put a breakpoint inside the handler so once the query is getting invoked it's automatically coming to our handle method which in this particular case is calling into the blog repository so let's step into this and this calls into the dynamodb context and returns the scan async result so let's return this now we can see here it returns as two blocks which was there inside the dynamodb so let's go to the amazon console so let's go to aws.amazon.com from the console let's navigate to the dynamodb instance for this particular region which is sydney which is the same as i used inside our application and go into tables to see the data here we already have the table named blog and we have two items under that this is exactly what is getting returned back by that api call now we see that there is a test and a test content so if we communicate back we can see there is a test and also the test content returned back in this response let's navigate back to visual studio and make sure to commit these changes so let's open up the git changes let's give a meaningful comment so let's say refactored to mediator and cqs pattern modified the get blocks method and let's make sure to commit all the changes going back to functions class we still have a couple of methods that needs to be refactored now let's do an example for the ad blog sync which in this case will be a command so here we are adding a new blog to the dynamodb database now in the add blog sync you can see this is getting the data from the request and reserializing it into a blog object and it is explicitly setting a new id and the created date timestamp it then saves this blog into the dynamodb context and responds back with a success message so let's refactor this to use the cqs pattern as we saw before this is modifying existing data so this needs to be a command so let's open up the solution explorer add a new folder under the domain and call this commands we can create a new class let's say add blog command now as before let's make this public and implement the interface i request since this is a generic type and we need to return but a command usually does not return anything it just modifies the data and returns back a void since we cannot use void mediator provides us a class which is called unit which is a null value so it represents a void instance since void is not a return value inside of c sharp now since this needs to add a new block let's take in a new property which is of type block so let's add the property specify blog and also specify blog as the property name now if we want to add a constructor so that this cannot be created without specifying it we can use the generate constructor and make sure to specify block now this checks for null and throws an exception automatically to implement the handler as before let's use public class add block command handler and use the i request handler interface specify that this is going to handle the add block command and it returns a unit which is empty so let's implement the interface as before let's take in the repository as the dependency so let's use the constructor and inject in the i repository of blog class now let's name this blog repository and add a backing field inside this class we can use this inside the method handle and call the save method so let's say return blog repository dot save and pass in the blog object from the request so let's call request dot blog now since we don't have the save method defined let's generate this method inside that interface now navigating to it it creates the save and returns a unit but let's remove the unit since we don't need to do that so let's navigate back we can call a weight and return a unit dot value explicitly so let's also make sure to add the async method because we have awaited here now this is complete so let's go to the dynamodb repository method which now expects to implement an additional method which is the save method now since we have the blog object coming up here let's call the save method on the dynamodb context so let's say return await dynamodb context dot save sync and pass in the blog object now this should be of type t because it's a generic repository so let's name this t and call this as item so let's also rename this as item and this is expected so let's go to the interface and also make this as type t and specify this as the item so let's save this go back to dynamodb repository and add in the async since we don't need to return anything let's remove this return statement so it bills as expected now coming back to our functions.cs we can modify this add blog async to start using the mediator so let's remove this direct call to the db context and call the await dot mediator.com and specify the new add blog command since this is coming from the command's namespace let's add the appropriate namespace and pass in the blog object in this case this is going to be blog now this is throwing an error because this has created an instance of the blog from within the host application so let's go back and delete this blog class that was existingly part of the host so let's delete this come back to functions.cs and make sure it is using the appropriate blog object in this case it has to come from domain.entities inside the startup.host let's make sure this also uses the appropriate namespace for block now since i know that the test project is also using an instance of the blog let's make sure to update the namespaces inside that as well now with that all fixed once i build it should be working as expected so let's navigate back to the add blocks command make sure to add in a break point here and run this particular project again now there is a slight issue with this lambda tool on the edge browser for some reason this combo box does not expand to choose the other options so let's use chrome and then start using it for our url interactions now you can see all the other methods that's available as part of the function so in this case let's call the add blog and then similar to we can use the api gateway request but now we need to pass in the name and the content for the blog inside of body so let's rename this test to be the name so let's say this is from app and add in another property which is going to be the content so let's make sure to delimit this with the slash since this is within the body which is a string we need to delimit it using the slash for the double quotes so let's say app content and again use the backslash and close this since these are case sensitive let's make sure to use the uppercase letters let's switch back to visual studio also put a breakpoint inside the add blog method and click execute from the ui it hits the add blog sync method and we get the request and the context as expected so if we step through this we can see the blog object now has the from app and app content as the properties being passed in so let's continue the execution which hits the add block command and the associated handler with that now this calls into the repository and the save method so this is going to add it into the dynamodb context so let's continue the execution this returns back the id as expected with this api endpoint if you were to switch back to the aws lambda console let's go to the dynamodb and refresh this and we can see a new record being created which is the app content and from app that we just passed in so we have also refactored the add blog sync to this new pattern so let's stop this open up the git changes and commit the changes so let's say move add blog to mediator pattern and let's commit all the changes in here going back to the functions functions.cs now you know how to change the remove block async which is going to be a command and you can move this exactly as before into a command inside our domain class and the get blog is also going to be a query like the get blocks async in this case the get blog is also going to have an extra id parameter which is going to be passed in as the parameter like we passed in the blog for the add command now by moving into the mediator pattern and using command and query separation we have separated out the different concerns so there is a host application that deals with the aws serverless hosting there is a domain which deals with our domain logic which handles and defines the commands and queries and there is also the infrastructure layer which handles the infrastructure related code which is basically in this case talking to a database there is a lot more cleanup that you can do in this particular function template which i'll do separately and push this up to the same repository so i'll add appropriate git commands so that you can go through it if you require now the other thing to note in the startup.cs for now i have hard-coded the credentials which typically i wouldn't do in a real-life application i would be moving this to an azure keyword or in case of aws i'll be moving it to a parameter store now you can pick and choose whichever works for you while in local development i choose to maintain them inside the secrets manager which is available as part of dotnet core if you are new to that you can check out my video linked here or in the description below i hope this helps you to understand about cqs mediator and how to apply this refactoring with an existing application now open up your current code that you're working look for classes that has more than four or five constructor parameters and see if there is a possibility to introduce this pattern now start slowly and introduce this one by one like we saw make sure to make git commit changes very frequently once you have something working now this helps us to revert back the changes easily whenever there is a problem we don't end up with having a huge pull request with lots of changes we can slowly and steadily improve the quality and the maintainability of our code base now this is exactly what we expect from refactoring in an upcoming video i'll also show you how to have test that is supporting these refactoring now since the default template didn't have many tests i didn't want to show that in this current video but if you want to be notified when that comes out you know what to do please make sure to hit the subscribe button if you like this video please hit the like button and also feel free to drop in comments or questions in the comments section below if you're there on twitter also make sure to send me a tweet i'll put my twitter link in the description below hope this helps thank you and see you soon
Info
Channel: Rahul Nath
Views: 1,741
Rating: undefined out of 5
Keywords: aws serverless project structure, dotnetcore command query principle, mediator dotnet, dotnetcore mediator, dotnetcore refactoring an application, refactoring to design patterns, aws serverless dotnet, serverless application template .net, serverless aws .net, serverless project structure for .net applications on aws, onion architecture dotnetcore aws, onion architecture dotnetcore, mediatr dotnet core, aws lambda mediatr, mediator pattern
Id: XE1w52pNYr8
Channel Id: undefined
Length: 45min 47sec (2747 seconds)
Published: Tue Apr 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.