Unleashing Clean Architecture in .NET 8: Exploring the Solution Template — Jason Taylor

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
foreign I'm Jason Taylor I'm a solution architect for increment and a Microsoft MVP in developer Technologies for those of you who don't know about increment increment is a technology services company that brings together highly skilled professionals from around Australia at increment I help clients to design develop test and deploy custom solutions to the cloud if you'd like to learn more you can jump online and check out increment.inc or you can ask me some questions after this presentation so it's great to be back here at the brisbane.net user group it's been one month for me I try to try to get here most months but I don't always make it and I'm really excited to be sharing with you my new presentation unleashing clean architecture with net eight this is a show and tell style presentation I'll be demonstrating the clean architecture solution template which is an open source project that I maintain and I will show you how to prepare your development environment how to install the template how to create a new solution how to build test and deploy the solution to production and then I'll tell you about some of the exciting features that are built into the template these features are designed to help you get your next project up and running quickly and to improve your productivity as a developer so that you can focus on delivering value to your clients let's get started so the clean architecture solution template provides a straightforward and a pressure a straightforward and efficient approach to Enterprise application development with clean architecture and asp.net core it's been built using the.net template in engine and so it's really easy to use you can create a new solution using.net new or even through Visual Studio 2022 by selecting the template uh you can see there I've got a little a little kind of metric there uh so far since it was created in October of 2019 I've got 66 000 downloads so I'm hoping I'm hoping to get that up to 100 000 at some point in the future thanks Todd uh so with this template it started out on.net 3.1 and I've upgraded it through five six seven and most recently eight and if you're going to be building a new solution a new asp.net core solution in the near future you probably want to consider.net 8 because it's the long term support version and I'd say in about six weeks we'll get that first production ready license with release candidate one all right so with this.net upgrade it wasn't just about changing the SDK to.net 8. I started to implement a lot of the features that people have been asking for for many years so traditionally the template was just angular and asp.net core now it supports react nasp netcore and you also have a web API only option database options not just SQL Server it also includes sqlite and I'll be looking at adding postgresql to this very soon security is now through asp.net core identity one of the most asked for features was a simpler security system so simpler authentication and authorization I've always taken the lead from the asp.net core team and how they built built their Spa templates and so traditionally this was with identity server that's been taken out now and so the spa templates are using identity server with cookie based authentication and the API template is using sorry I said identity server didn't I asp.net core identity with cookie based authentication and the web API template is identity with token based I've also built a complete CI CD Pipeline with infrastructure as code based on Azure bicep and so that's all of these things are templated and that means when you go.net new these things are produced based on the options that you've selected and you'll have a custom CI CD pipeline built on GitHub actions with custom bicep templates so this is of course still freely available and open source on GitHub if you like it please give it a star that really helps keep me motivated and so you can find it at Jason Taylor Dev forward slash clean architecture all right so installing the template is very simple I'm going to demonstrate this soon but you get to see my nice animation where I install it so this.net new install clean.architecture.solution.template that'll install the.net 7 version okay because we're currently running on a preview version of.net8 and so the preview version of the template as well so we need to specify the version and I'll show you how to do that soon once the template's installed it's really easy to use you can use it from the command line using.net new DOT net new ca sln it's got a number of options name and output which come from the net new command but also client framework so as I said you can choose between angular or react and if you specify none it'll just be a web API Only Solution you can also specify that you'd like to use SQL Lite instead of SQL Server so look at changing some options I add in some options there to support postgresql so when you do create a solution and you say specify I want angular and I want sqlite the solution will produce exactly that so it'll have an angular front end with an asp.net core backend sqlite set up with Entity framework call with migrations already produced for sqlite so it's ready to go so that's an example of how you could create a react solution so that would be react front end with an asp.net core back end all right if you're doing it through Visual Studio it's even easier just find the clean architecture solution template click on it and click next and choose your options through the IDE a some of them sometimes that sort of stuff could be a little bit hard to see so I might just zoom in a bit Yeah Todd and you don't have to install anything yeah yeah you have to install the template so this is like a nice option that you get when you install a.net template through the command line you can also see it in Visual Studio it'll used to be a lot harder to to see your templates in vs all right so let's start out with the demo let's deploy the solution to production obviously we've got a little bit of work to do there but it does take time to deploy to production so I wanted to kind of kick that off really early so we're going to set up our development environment we will create a new solution build tests and run the solution locally and then we'll deploy it to production so I am let me bring up my cheat sheet okay so first thing we want to do is to make sure that we're running the latest version of.net so if I go.net version or we just go.net list sdks we can see the latest version I have is.net8 preview six and that's fine now I'm a running on a Windows machine so if I wanted to check to see if there was a new version available and install it I could go Microsoft Dot there it is SDK preview so I could actually go and I'm not going to run any of these winget commands tonight but it's really nice to be able to run these commands quickly and efficiently from the command line up the back can you see this okay it's pretty good yeah okay good all right so I have net installed I'm also going to be using the GitHub CLI so I could also install that let me let me grab it here so GitHub CLI from the command line we can get installed github.cli it's really cool tool okay but I already have the GitHub CLI installed so the next thing I want to do is make sure I'm running the latest version of the template so as I said it's dotnet new clean architecture solution template and then the version so you can see here I've just used a wild card so 8.0.0. some preview version whether it's a release candidate or a preview six or preview so it doesn't matter so it's going to go and install that so it says 7 6.17 is already installed and now it's going to install it again for me so make sure I have the right version so you can see this is the what's called a.net project template it's my clean architecture solution template and this is a.net item template and so the project template will create the solution whereas the item template will scaffold some code within the solution and I'll show you that later on so it makes it easier to create new features within your application so I've got the template installed I want to make sure that I am authenticated with GitHub so I'll just go get what does it get Hub auth status and it'll say yep we're good to go and I also want to make sure actually no that's all we need for right now so let's use the GitHub CLI to create ourselves a new repository on GitHub so we go GitHub repo create we'll call this one priz.net and so this interactive way I can do it if I just press enter there to give us a bunch of questions and we can create that repository but I'm just going to provide options for um to make it public was that already there yeah okay good um I will create a public repo and I will clone it and so that means it's going to create the repo it's going to clone it locally I can jump straight into brizz.net and we're ready to go with an empty Repository now I've got the template installed so I can go Dot net new ca solution and if I wanted to learn more I can go help okay and so that's going to see some of the options that we saw in the previous slide but basically we now going to create a new solution so if I go.net new ca solution I'll give you guys a choice do you want to do angular or reaction tonight react okay and so we'll leave it with SQL Server uh and it's going to Output into the current directory so the dotnet templating engine is going to look at the current directory and it's going to say well this directory is called briz.net and so that means it's going to create a new solution called briz.net and the namespace is inside it are going to be bris.net so everywhere it finds clean architecture in this template it's going to be replaced with briz.net so that includes the CI CD pipeline it includes the bicep templates it includes the source code it includes readmes all that sort of stuff uh so we're good to go so why don't I just get this committed we won't push it yet because that will trigger the CI CD pipeline when it's when it's uh ready to go and we'll go get commit new project like that okay so I do want to show you how all this works but before I do that I want to trigger the CI CD pipeline so that I can get this deploying through to different environments so to do that I need to set up the GitHub repository there's a few environments I need to create there's some variables that I need to create the secrets that I need to create so it can communicate with Azure in Azure there's resource groups that I need to create there's uh app registrations that I need to create in Azure ID and so there's a lot of work so obviously if we were starting a new solution we had to do all of this from scratch it would take a long time but I don't want to do that I want my solution templates whether it's the Blazer one or this one to be really quick to get up and running so that I can focus on delivering business value okay and so I've put some scripts into this template now to do all of that for me so this script will tell us exactly what it's going to do when we run it okay so it says this script automates the setup of environment resources credentials for a project hosted on GitHub and deployed to Azure it creates workload identities in Azure ID sets up resource groups and configures environment specific variables and secrets in GitHub repository this group leverages Azure CLI the GitHub CLI and GitHub apis to perform these tasks it aims to streamline the process of setting up and configuring development staging and production environments for the project and this script does have parameters it's a Powershell script with parameters but it's done its best to guess what they might be because we didn't provide anything and that's where it's using the GitHub CLI and it's using the Azure CLI so I need to look at this and make sure I'm happy with this is this the right subscription ID and if I'm not happy with that then I can go in to the Azure CLI and I can change it I can say Azure oh sorry AZ account set subscription so all of this has been uh gathered for me now you can see in the environments it's going to create a development environment a staging environment and a production environment and then it's got a warning it says running the script will provide various operations in your GitHub repository and Azure subscription ensure that you have the necessary permissions and understand the consequences so don't run this script without understanding exactly what it does okay and in case you didn't see the warning there's a disclaimer use the script at your own risk the author and contributors are not responsible for loss of data or any unintended side effects resulting from running the script so that being said I will go ahead and run the script the default option is no all right but I'm going to run it so it's going to go away and it's going to set up a bunch of stuff for me now while it's doing that I've got a browser handy let's see yep I got one here but that one is not going to be enough because I need to be signed into GitHub so we'll bring this one over I'll hide all my bookmarks favorites uh never there we go okay so we created a repo called british.net and we just have a couple of manual things we need to do so that this pipeline's going to be able to run so the first thing is we need to give the workflows permissions to read and write the GitHub token so that's used for authorization whoops so we just set read and write there and scrolling down we hit save now the script that's running in the background it's finished now the script that's running in the background created some environments for us in GitHub so we have a a development production and staging environment and it's also created some Secrets the SQL admin password and three variables so one thing that I can do is I can come into an environment and specify a required reviewer I'm not going to do that tonight because I always forget to approve it and then the pipeline never finishes but but I can come in here and I can say yep I want to be one of the required uh reviewers for this particular pipeline if I scroll down to secrets and variables we can get a bit of a glimpse at what's in here so you can see for secrets we have we have environment specific secrets and variables now in GitHub actions which is really nice so I've basically got the agile SQL administrator sorry the Azure SQL administrator password for production staging and development I don't know what that is that was generated randomly by that script that we were on the setup.ps1 script I don't need to know what it is because it's going to be passed through to to the bicep templates and it's going to end up in key vault as a collection string so that's fine it's sort of the variables here we've got the Azure client ID which is the app registration which lives in Azure ID and we also have the Azure subscription ID the tenant ID and the project name so this tenant ID subscription ID and the client ID I used for GitHub actions to authenticate against Azure using that app registration project name is pretty obvious here we have the default username for the SQL administrator and we've got our Resource Group names so all of this is of course being created automatically for us and if we go into the Azure portal we can see some of the things that have been created in there and the focus of this talk is not to teach you how to do all of this it's to show that when you focus on your specialization and you put together the right tools Technologies and approach you can deploy to production really quickly and focus on delivering business value we're basically establishing a pipeline of value on Day Zero okay and so this is my specialization this is the way I'd like to do it but you might be able to learn from this and Fork it or create your own or do something completely different so you can see here the resource groups are all there I'll Zoom that in to 150 percent so there's our brizz.net resource groups and if we went over to they're empty at the moment if we went over to Azure active directory I need a bit more space for that and go into app registrations we have we've got a glimpse of them but then they disappeared we've got these app registrations representing the application running in different environments and associated with that are some credentials so one for an environment specific these are these are used by GitHub actions to authenticate against Azure one that's not environment specific and one that is environment specific okay so with that in place and the pipeline set up and the workflow with the right permissions all I have to do now is go get push okay normally of course we're going to create a feature Branch to a pull request all that sort of thing get it approved and that sort of thing we don't have time it's Thursday night and really we want to get some beers soon so we're going to skip that so come back over here to bris.net and go into actions and we can see the pipeline has kicked off and I'm going to walk you through exactly what each step of the pipeline does but essentially it's going to build the project test the project package the project deploy it to development staging and production and make sure that the database which will also be provisioned is actually up to date and running the latest migrations whatever that might be in our solution okay so well that's happening let's go into this one I'll drop back into brizz.net and I just want to give you a quick peek at the solution so we'll go so the first thing you need to know is don't do what I just didn't load up visual studio 2022 we've got to load up the preview version because some of the some of the earlier versions of net 8 preview worked in Visual Studio 2022 but there's been some issues recently that I've run into so just use the preview version I changed that theme this afternoon to do a screenshot it looks so old I'll leave it like that for now though so if I go file start window clean architecture and we'll zoom in okay so out of the box you get your four layers so webbeing presentation domain and application layers representing core and infrastructure all of your external concerns such as data access you also get a bunch of test projects so for domain and application there's some unit test projects but there's also some functional test projects which will exercise the they're basically system tests so you can run those against a live database with live services uh for web we have acceptance tests so those acceptance tests are running uh playwright and spec flow and we also have a uh an empty project at the moment for infrastructure which is the integration tests so you get this out of the box something cool that I added recently which I kind of kind of like is I've also added a default readme uh it's not that I'm sorry I I didn't load the brizz.net project this is the actual um the clean architecture solution template we need to load the press.net one because when it's generated through the.net template in engine it's quite quite different so here's our readme for our briz.net project so it generated a starter readme which is going to be great because you always need a readme so that everybody on the development team's on the same page about how to build run tests and you know basically deploy the solution so that that comes out of the box you can see there's an editor config so that there's consistent coding code Styles and formatting a lot of this I'll cover later on in the talk so I think you can see the classic structure is still in place uh and that'll help you get up and running really quickly so if I come back over to here let's do a quick build so.net build TL does anyone has anyone seen this command it's really cool so I can't remember oh yeah terminal build output so don't add you dot net build has a new Option and net eight to produce more modernized output so the terminal logger output groups errors with the project that they came from and it better differentiates the different Target Frameworks for multi-targeted projects and provides real-time information on what the build is doing which is pretty cool if you like to work in the command line now on this side over here I'm going to just get a few things ready CD Source City web and we'll go.net run so we'll just launch the web project and over here we'll get ready to run our tests so dot there we go dotnet test no build okay so this is going to run all tests in the solution so it'll run our unit test it'll run our integration test our functional tests and our acceptance tests uh let's just see that it started okay where did that where did that land not there this one that should do it here we go so that's our that's our react application of course we could go and sign in and all that sort of thing but I really just want to run the tests at this stage there we go to give that a second all right that always gets me but that's okay this is because I'm not running Docker so at the moment the functional tests can run in three different ways if you chose sqlite they'll run against uh the local sqlite database if you chose SQL Server they're going to run by default against test containers so SQL server and Docker and that'll get spun up automatically for you and it'll get cleaned up afterwards for you the third way that you can run it is it can point at a actual SQL server on your development machine and that Third Way is my preference for SQL Server because the fact of the matter is that that container whether that that real live SQL Server whether it's in a container or not is already running is already ready to go and so when I run my functional tests against that I don't have to wait for the container to be spun up and then the tests to run and the container to be removed it's already ready to go so it's just a little bit faster about nine nine or ten seconds faster not that I did any serious benchmarking on it so we'll go ahead and run that again and so you can see that when you when you use a template like this there might be a lot that you're not familiar with there might be a lot that you haven't seen before or maybe this is all um normal for you but you can come into this template and you can see how it works it's already working all the way through to production and you can ask questions on the GitHub repository and have discussions with other users so there we go I think all of those tests pass so that's good and that's really what I wanted to demonstrate as part of that uh part of that demo and it looks like everything's coming along nicely here so it's just started its deployment to development and deployment to development will include things like deploying the infrastructure initializing the database and actually deploying the website so we'll get to see that once it's finished all right yes question when I'm running SQL Lite do I run against files or in memory that's a good question so when the web application runs it's running against files but when the functional tests run it's running in memory yes yes so it is yes but only because I haven't configured the pipeline to do an approval so generally what I will do is set up an approval for the staging environment and the production environment and so it won't go through automatically unless there's an approval but there is still just one single build artifact for the website that gets promoted from development to staging and then to production so it's the same artifact that will move through the pipeline any other questions yeah yeah what licenses am I oh sorry I should I should repeat the question so the question was what license is the template released under it's MIT um I guess that's the most permissive I think of them because just out of Interest with templates like this there's the license of the template code apply to the code generated by the template yes I believe that's specified in the in the license yes oh yeah so so good club um steps yes um really just one yeah correct so the question was I did a a manual step when configuring the GitHub repo which was to enable read and write access to the workflow for the GitHub token and yeah I haven't found a way to do that either through the CLI the GitHub CLI all through the GitHub API so if someone does know a way to do that I'd appreciate a heads up okay thank you all right so now we get to I get to show you some of the things that I found exciting and I think you might find exciting that came through in this upgrade so the first thing that I found exciting was framework and package management so I've simplified managing Target framework and dependencies of projects across the solution so the required.net SDK version is specified in global.json now admittedly I know that that's not very exciting but it's important to remember that although generally speaking global.json is optional because you can always run on the latest SDK for this particular solution it's used in the pipeline to make sure that the correct SDK is installed on the build agent so so we do need global.json in this case unless we were to go and change the pipeline the other thing that's a bit exciting is the required.net runtime version is specified just once in directory build.props so directory build.props has some common properties and that will get applied to all what eight projects that are in the solution so if I want to change in the future from net 8 to net9 I just change that in one place Plus global.json you can see there's some other common properties there treat errors as treat warnings as errors so that people can't check in code with warnings because that's really annoying um you don't have to have that conversation anymore implicit usings are nullable just across the board all right so package versions are managed centrally in directory packages.props so I've enabled the central package management feature which came out sometime last year and all we have to do is have this directory packages.props file set manage package version centrally to true and then all of the different packages that we have we list in this file with the appropriate version and so that means if I wanted to upgrade any unit across four different testing projects I just changed the version here and I don't have to change it inside of the individual project files yes question this so it kind of really doesn't work any differently so once you have directory.packages.props you list the versions you list all of the package and all the versions that you want but then your CS proj just lists the package so this is the Project Specific one so lists it without the version so it's nice nice and simple yeah yeah so let's let's think about the next so if we go go back a little bit here if we think about when I upgrade to.net preview seven I only have to change two files global.json and directory.packages.props I don't have to change eight different projects so I thought that was really exciting I really like that so there's a combination of features there yeah the question was um does this um uh what is it called again Central package management yeah Central package management does it only work with nuget or does it work with other repositories I believe that it only works with nuget because I believe it's actually a feature of nuget that's exposed and available so all right dependency injection so dependency injection in the template supported using the built-in.net dependency injection container that's nice and simple but I like to split it out with project service dependencies registered in a dependency injection.cs file so the way that works of course is I created an extension method on i-service collection so in this case we're doing it for our infrastructure project so I have a dependency injection file in the root of the infrastructure project an extension method called add infrastructure services and inside of this method I'll wire up all of the services that are related to infrastructure and then in the composition route which is generally program.cs I will just go ahead and call all of those extension methods and because I've built it as kind of a little fluent API I can just say add this add this and add this and then we're done and that keeps program.cs really clean right so I've even got one there for the web project there so that's sitting in the same same project but nice and clean well for me it's just that I get to use the simplest approach and the simplest approach is not always the best approach but it's kind of one of the goals of the template the goal is the simplest approach to Enterprise application architecture with asp.net core and so if I bring in too many other packages like say Auto fact or fast endpoints bring in the package just the yeah well this is I mean yeah yeah that's right well I guess it's essentially essentially for me it's the same end result I have a nice clean tidy place where I can Define my dependencies and uh it keeps my composition route looking very clean another question correct so the question was so to have that work the various projects would need to depend on some kind of dependency say say the Microsoft dependency injection abstractions project and is it is it what was the second part to it sorry yeah mainly yeah right yeah yes yeah so in in so in taking this approach then there might be a dependency say on the domain layer for um certain packages that probably shouldn't be there and so with clean architecture you know the goal has always been to be independent of anything external so it's independent of the UI independent of the database independent of Frameworks and and that sort of thing so if we take a really pure approach to clean architecture then yeah we probably want to avoid that in this case there's no dependencies being wired up in domain um so so that so that particular issue is not a problem but there is an application and infrastructure and web so I don't mind I always tend to take a bit of a pragmatic approach to clean architecture and so if you look at my application layer I've got a dependency on Entity framework core I don't have a dependency on a specific database but there is a dependency on Entity framework core and a few other things I'm trying to zoom in there uh and that and that's because I feel that the value proposition by not being dependent on an orm is not worthwhile to me I don't tend to change an orm it doesn't mean that I'm not ever going to implement a repository pattern or a unit of work I might I just have to figure out what problem that's going to solve so yes clean architecture being very pure and adhering strictly to the principles is one thing but I tend to take a pragmatic approach so they'll they'll there will generally be a compromise and and uh you know the question as to whether you should do one thing over another will always be it depends yeah okay yes I think um at the moment you've quite often see you promised you promised that you would walk out if you if I showed you something dirty in my clean architecture implementation yeah you see with the parents injection now they've got the pregnancy injection abstractions yes yeah and they think yeah I think anything foreign yes having that but yes solve a few arguments I think in that space I agree and so yeah so Brendan Brendan was sharing his opinion on um the the the the use of abstractions such as dependency injection extractions actually I was looking in the Cs project to see where I'd reference that I'm sure I'd referenced it in the past in certain projects in order to extend I service collection but I couldn't quite and he raised a very good point that it would be good if Entity framework core had some extraction so you'd be taking dependency on the abstraction instead of the actual framework but you know what I think that's the thing about Entity framework core it is one big abstraction it's an abstraction on the database so I can even though I have a dependency on energy framework core in the application layer I can switch to sqlite I can switch to SQL Server I've already proven that I can switch to postgresql any of the databases that are provided by any framework core I can switch so I get to use the RM directly and I don't have to jump through too many Hoops to leverage its powerful capabilities yeah well maybe no problem all right so next web API so it includes a a API built using asp.net core minimal API now I've built in some minimal API extension methods which support some defaults such as open API and some routing conventions because minimal API is fast and lightweight but a lot of the things that we know and love such as conventions are just not built into the framework at the moment now of course I could have gone on and chosen something like file standpoints but I really wanted to keep it simple and for me keeping it simple was using ASP netcore minimal API and seeing if I could get it to work in a way that I really liked now we have a lot of options for how we organize our API endpoints right we've all seen the demo where we have a tiny web API with one file and all of the endpoints are defined in that file and I think that that option is okay right if you have a very small service with a small number of endpoints and minimal logic in those endpoints right for a crud application with maybe only one or two entities the other option that we've seen is we can group endpoints into separate files such as this one get where the forecasts so this is a good option for where perhaps we're building an Enterprise API and there's quite a lot of logic in each endpoint we can kind of start to separate each endpoint into its own file perhaps into its own folder and in that folder we can have the endpoint we can have the request type the response type we'll have this nice little slice for that particular endpoint and we can go to that folder and work on that endpoint the other option is we could group related endpoints into a single file such as users.cs so all of the endpoints that are related to users will sit inside of this file and I think that's a good option again for an Enterprise API where there are a lot of endpoints to manage but the endpoints themselves don't contain very much logic now those are the type of endpoints that I have in the clean architecture solution template because my endpoints are only concerned with figuring out what type of request it is and passing it on to some Handler which lives in the application layer so my endpoints are quite small so let me show you what it looks like groups of endpoints are defined in separate files so I created an abstract Base Class called endpoint group base which defines a map method okay so this map method accepts as a parameter the web application and it calls map group now minimal API has a map group but this one's actually an extension method that I built and allows me to pass in this class an instance of weather forecasts I use that information to set up some defaults such as the group name is called weather forecast based after the class name I use it to specify tags so that the open API specification generates correctly I use it to specify that we do want to add open API so all of these defaults are built into my extension method and this map get well of course minimal API has a map get but again this is one of my extension methods I'm passing in the method that you see below which contains all of the logic for getting weather forecasts and do you see what I mean when I say my endpoints don't have much logic in them they're usually just one or two lines of code so grouping a set of related endpoints into a single file works really well for me so we've got the endpoint group base we've got the map Group which is an extension method and map get which is an extension method and of course there's a whole host of other extension methods to support put post delete and and different combinations of that so the endpoint groups are automatically registration registered you don't have to register them one at a time I've just created an extension method on web application you just say map endpoints it will look for all the endpoint group bases and just call map for you so essentially wires it up and that's been working really well for me I've got an example of another endpoint group later on and I'll show you show you why I think it's working well oh yes one of the other things that we've got in.net 8 is the new eye exception Handler so this works with the unhandled exception middleware and essentially it allows you to improve your exception handling with IX with I exception Handler which gives you a callback for handling known exceptions in a central location so you can see in this case I've got a custom exception Handler implementing I exception Handler and we've got this tri-handle async method and so inside of here we can create some logic to handle known exception types and if we were able to handle it we can return true otherwise false now in the template when you look at it I have a list of known exceptions that I will try to handle and I'll I will craft a more appropriate response but with this approach it kind of made me think well I don't have to just have one exception Handler I can have multiple so you could actually say this is the not found exception Handler this is the validation exception Handler whatever common case it is it is that you have that you'd like to manage and you can see there that I've got Services dot add exception Handler custom exception Handler so if you had many obviously you'd probably create an extension method on that to wire them up automatically the the old filter does I exception Handler replace the old exception filters no so it's an alternate option so this one is working through middleware so a little bit more Global the filters are still available and and you can manage exception handling through the filters I like this approach because I don't have to specify on each of my endpoints add this filter admittedly of course with the solution that I built it would be very easy to do so because I would just do it as one of the options when I call my map group extension method but yeah yes question to no this this happens as a no that's all right so the question was do you need a try catch to call it no this happens as a result of the exception and it's automatically so asp.net core the middleware which is which is dealing with these exceptions we'll call this filter and if it's able to kind of handle it if it returns true then that'll be the end of processing but if it can't it'll see if you've got some other exception handlers and it'll try them too otherwise it'll fall back to its default response so you'll get your 500. okay open API so of course the template includes open API support to improve productivity and easily adapt to API changes it generates an open API specification based on the included web API and it does that whenever the web project builds so you know your specification will always be up to date uh developers can of course use Swagger UI to visualize and interact with the endpoints now it also generates an angular or react typescript client based on the web API thank you the angular client is just as it always been but the react typescript client needed a little bit of customization so I'm using nswag to generate these clients the react client has a custom template which will handle the new ASP net core identity authentication correctly so if it returns a redirect to login that'll be handled automatically and so that works both for angular and react so this is really cool this is one of the really great productivity things when you're building your angular or react front end you don't have to manually write HTTP client code to interact with your API you have strongly typed interfaces and types and also strongly typed response and request types I've also included a web.http file if you prefer to use that and so if you haven't seen this this gives you a way that a little bit of a playground where you can interact with your API and it might be a little bit hard to see up the back there but in this particular one I'm demonstrating some of the capabilities of the new asp.net core identity API which I haven't talked about yet we'll get to all right authentication authorization is the next topic so as with the official.net 8 Spa templates I've migrated these ones over to asp.net core identity I mentioned that angular and reacts bars will use the default ASP Network identity UI with cookie based authentication and so that means you get all of those razor Pages for free and you don't have to build say login and register and profile and email all those sorts of things you can of course customize them but if you don't want to kind of mix those mix those things together you can now use the asp.net core identity API and so here I think I've got a highlight there yeah here I'm adding the identity API to this web API solution and it'll provide you some endpoints you'll see in a moment register login refresh that you can use so if you wanted to you could actually write your own UI in angular and react to manage login and register and all those sort of identity concerns and communicate with this backend API now I really like this I I was I talked to Brandon about this one day and we were we were on a run and I said I think I've done a good job with the minimal API implementation with the extension methods because when this map identity API became available it just seemed to fit really well into my implementation I created a new class called users it's inheriting or based on the endpoint group base the map method Maps the group so we get all the defaults like forward slash API users for the base route and all I had to do because it was an extension method was called the built-in method.map identity API and it looked really simple to me uh and and uh yeah I was happy with that result so I think I think I've taken the right direction all right so this is this is an example of the endpoints that you would get so obviously they can because it's part because it's part of the minimal API they'll go ahead and make them their way into the specification and if you have it so configured also into your angular and react typescript clients by default it's not configured to use identity API but it's just a matter of adding that uh that endpoint group base all right data access dot access is this is a little bit boring this slide I'm going to work on this one a little bit so just bear with me so data access is supported using Entity framework core either sqlite or Circle SQL Server those are the built-in options of course if you wanted to change to something else like postgresql today you just go ahead and delete the built-in migrations and change the provider and you're pretty much there you'll have to update the infrastructures code as well so the EF core migrations is enabled and it's almost completely automated you have to still create your own migrations but the rest of it is done for you for example database initialization and seeding which means creating the database applying the migrations and seeding the database occurs during startup for development environments so your local development environment don't have to worry about it for the deployed environments it's using the Entity framework core migrations bundle and that's a cross-platform app which will ensure that your deployed database as configured using a connection string is up to date with the latest migration so we build the CF Core migrations bundle in the pipeline and we run it in the pipeline for each environment so where we need to configure our entities where we're not happy with the conventions we want to override them the preference is to use EF core fluent API and so you'll see some examples of that in there and I also have some EF core interceptors to implement cross-cutting concerns such as auditable entities and dispatching domain events I'd love to show you just how clean that is because that's something that I was really excited about if you've worked with interceptors before you might agree with me and saying that it's not really very nice to wire them up like a lot of people will inject them in through the Constructor and then in on configuring register them well I don't have a Constructor well no I do have a Constructor I lied sorry my apologies I do have a Constructor but it's not doing that and I don't have on configuring so my appdb context is nice and empty but I'm still wiring up those interceptors so let me show you how I did it so I can't see that dependency inject that's the one so you can see here I just register the interceptors with dependency injection and then when I add my DB contacts I'm just telling that hey just add all of the interceptors use the service provider get the services anything that's implementing I save changes Interceptor and add it in so we can configure it here rather than in the appdb context and that's much cleaner I like that all right core features so core being application layer and domain layer has a number of features built into it such as automatic validation of invoked use cases now example of a use case might be create a customer or dispatch an order and those are the types of things that live in the application layer we also have the ability to specify authorized requirements for use case so if we have specific authorization requirements for a use case we can add an authorized attribute to that use case and specify those requirements now you might be a little bit worried there that that's kind of got a dependency on some kind of identity tooling it doesn't it's an abstraction I created the authorize attribute and the process to run it is relying completely on some implementation sitting in infrastructure which in this case is ASP Network identity but yeah we automatically log unhandled exceptions this is the some of these features the first one this is the second one and third one these are powered by mediator pipeline behaviors so if you haven't seen that sort of thing I'd encourage you to check it out I automatically log the details of any invoked use case so when our request is made to the system such as dispatching an order I will log that request I will log the input to that request and I will log uh the user who yes question not at this stage yeah that's something I've got a massive backlog and yeah there's a lot of things that I want to add to it but look listen um that that's a good question so the question was are you using open Telemetry and my answer of course was not at this stage something that I want to look into um if you do like to contribute to the to the template at any point I love contributions just keep in mind that the goal of the template is always the simplest approach to Enterprise architecture with asp.net core so I might not add in advanced caching capabilities but I might improve how logging is done simple things add and dispatch domain events is built in support for Value objects is built in and support for auditable entities is built in CI CD pipeline this was something that I worked very hard on so this is the CI CD pipeline as I mentioned it's based on GitHub actions and it deploys to Azure and manages the infrastructure using bicep templates so when a developer does the right thing and raises a pull request and that gets reviewed and approved and merged into main that'll kick off the CI Pipeline and that will build test and package the solution when it packages the solution it's built in The Entity framework core migrations bundle and the website the publish output of the website we'll then kick off the CI pipeline for each environment in the in in that's configured it will deploy the infrastructure using uh Azure and it will initialize the database using the Entity framework called migrations and that's really good right because this is a step on the deployment pipeline if the database fails to initialize you'll know about it much better than initializing it at startup when the application has been deployed already and users are using it but can't access their records so it's part of the pipeline it'll it'll fail much faster and then of course we deploy the website so that's development staging and production all right infrastructure is code so the template includes infrastructure as code using bicep templates it includes the components necessary to support a basic web app and that basic web app the infrastructure design is based on the Azure reference architecture for a basic web app so you can see the link there if you would like to learn more about that architecture so there's a lot like to align what I'm doing with something that's backed by a proven approach so if you'd like to learn more about this you can jump on on Microsoft learn and check that out all right code scaffolding so it includes built-in support for scaffolding new use cases as either a command or query because the template implements cqrs so use cases represent specific application logic such as create customer or dispatch order and when you use this CA use case template you'll want to use it within source application that's where it's been designed to create these use cases so essentially you'll go.net new use case you specify some options the name represents the name of the use case being created feature name represents the feature that this use case belongs to use case type either a command or query and the return type the name of the type being returned that can be whatever you want it to be maybe you haven't created it yet there's a demonstration of creating the dispatch orders use case so we go.net new see a use case feature name orders name of the use case dispatch order and the use case type is command so the customer that I don't have an example of the code that generates so I'll just I'll just do that now for you quickly so we want to jump into source and into web sorry not interweb into application follow my instructions go.net .net new ca use case thank you I was wondering where my intellisense was .net there we go I don't want help I want there we go that'll do so we'll create a new use case in the feature called weather forecasts and the use case name will be get today's forecast and the return type will be a type that doesn't exist yet it'll be the today's forecast VM so if I press enter on that there we go it fails okay I must look this is one that that I tried earlier that didn't work because I specified all the wrong things but I can fix it okay missing our use case type we can we can cover that too that's UT and this is a query boom got it okay so if we come into here and into application I'm going to zoom this in for you okay so I've got weather forecast folder if that folder didn't already exist that's the feature folder it would have created it inside of that there's a queries folder so I separate the queries into the queries following the commands into the commands folder it would have created that too here is my get today's forecast feature and here is the uh sorry feature use case and here is the code that it's generated so this is just to help us get started there we go so I have a query which is the input for the query we could put some parameters in there you know we might want today's forecast with um specific data return we can Define that we've got a validator so this is uh fluent fluent validation we can specify some validation on this input and we have a Handler and you can see it's just gone and basically created a skeleton for us to start working with so we don't have to go and create this folder structure in these files and that sort of thing so be interested in everyone's feedback on that if they do start using it what else do you want to see what options do you want should I include mapping should I make it optional whatever you whatever you need we can build on it because it's it's pretty easy to create these item templates all right documentation as mentioned it includes a readme.markdown file which is generated automatically and the file content is based on the type of solution that you create so the readme will change depending on whether it's react or angular or web API it includes basic details such as the template version used to create the solution so you know you know if you if you decide to upgrade to a new version of clean architecture solution template you can kind of compare those versions it includes how to build and run the app code scaffolding to generate use cases details on code Styles and formatting which is basically use editor config running automated tests and where to find help and other resources all right we just need to check our production deployment make sure that was successful so over here somewhere isn't it there we go so is this the right one all right yeah no that's right okay so that was our deployed to development you can see staging and production went through we'll just click on one of those sites just to see that it's running so this will be the first time that's run so of course deployed all of the infrastructure to initialize the database websites up and running it's all wired into application insights so there's Telemetry coming from like key Vault and from SQL Server the the actual logical server and the database itself so that yep that's all up and running oh always really focus thank you so we will check the other environments because you can only see so much hello world all right so I hope you enjoyed my talk tonight if you're Keen to learn more or hopefully contribute to the template you can access the project on GitHub there you can have a discussion with other users you can request a new feature you can point out a bug for me I'm on top of it at the moment so there's not any pull requests waiting to be merged or there's not really any issues that I'm worried about there's just a few there so if you do put something through it's likely that I'm going to respond very quickly if you do find the template valuable please give it a star on GitHub that's uh that's what I thrive on at the moment is GitHub Stars so I'd really appreciate that thank you foreign
Info
Channel: Brisbane dotNET User Group
Views: 11,578
Rating: undefined out of 5
Keywords:
Id: jhgxdDhNicI
Channel Id: undefined
Length: 62min 54sec (3774 seconds)
Published: Mon Aug 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.