1 00:00:00,000 --> 00:00:17,000 Hello everybody, I'm Nick and this video, I'm going to show you how you can create your own project templates in dotnet now that catalyst for this video is actually a lot of people's complaints about Microsoft removing the original web API template from dotnet five to dotnet six and replacing it with a more minimal vision. 2 00:00:17,000 --> 00:00:34,000 So in this video, I'm going to show you exactly how you can make your own ones and even publish them and you get to share them with your team. I've personally never worked in a team where we don't have our own templates of Microsofts, so whatever knowledge you gain here can be applied to basically all of your projects and your company. 3 00:00:34,000 --> 00:00:47,000 If you like our content and you're going to see more make sure you subscribe but in this notification bell to get a little bit of a new video. So let's start from where it all began. We have this old template and this template is the dotnet five template and for web API. 4 00:00:47,000 --> 00:00:57,000 And you have your controller here basic stuff. And then you have a program dot CS that points to a startup dot CS and you have the ihost builder which you run here to spin up an API. 5 00:00:57,000 --> 00:01:08,000 And then you have the startup dot CS which has a configuration, the configure services method that you use to configure your services and then the configure one which is used for middleware configuration. 6 00:01:08,000 --> 00:01:19,000 So all very nice and very beloved then Microsoft and the only thing I've done to create this project is I went here and I selected web API for dotnet six not dotnet five. 7 00:01:19,000 --> 00:01:28,000 I went ahead and they use the new feature so implicit using statements here we only have one and then filescope namespaces so that makes sense. 8 00:01:28,000 --> 00:01:37,000 But then there is no longer a startup dot CS and now if you want to configure your services you do that here and if you want to configure your middleware you do that here. 9 00:01:37,000 --> 00:01:46,000 I totally understand why people might not like this approach. So let's see how we can make our own template. What I've done here is I used the dotnet five web API template. 10 00:01:46,000 --> 00:01:55,000 I create the project targeting dotnet six and I use the features I liked for example implicit using statements or filescope namespaces. 11 00:01:55,000 --> 00:02:05,000 But then I put the startup dot CS back and the program dot CS the way it was. So how do we make a template out of this? Well before I show you that let me make sure we're all on the same page. 12 00:02:05,000 --> 00:02:21,000 So in dotnet you can actually use the dotnet new command and this new command is used to create a new project based on templates. So I can say dotnet new double hyphen list and you get a list of all the installed templates you can use in this machine. 13 00:02:21,000 --> 00:02:34,000 One of them is the console for example and you can do dotnet new console. Oh and let's say my console app and if I am to press enter this will create a new project using that template. 14 00:02:34,000 --> 00:02:44,000 We're going to make our own of these basically. So how do we do that? Well let's load the project here. So this is the exact same project is just on VS code and I will explain why I'm doing that. 15 00:02:44,000 --> 00:02:53,000 So what I want to do is I'm going to go to the very top level. I'm going to add a folder called dot template dot config. It's just a special name for the sort of thing. 16 00:02:53,000 --> 00:03:06,000 And I'm going to add a file in here called template dot Jason. And these Jason five is where I'm going to describe my templates properties. Now because there's quite a bit of box standard properties I'm just going to paste them here and talk you through them. 17 00:03:06,000 --> 00:03:16,000 So first you have the schema you can actually go to that URL and see the schema that is supported in this project templates syntax. Then you have the author me specifications. This can be an array of anything. 18 00:03:16,000 --> 00:03:27,000 It describes what are the concerns of this template. Then you have the identity which is basically the ID then name and that's a short name for your template and you can have a short name. 19 00:03:27,000 --> 00:03:38,000 And this is what's going to be used here. So if I do again, I dot net list, this is the short name and this is the name. Then the source name is actually a special one. 20 00:03:38,000 --> 00:03:48,000 What it will basically do is it will try and match that string anywhere in this template and replace it with whatever you specify as the name of the new project. 21 00:03:48,000 --> 00:04:02,000 So if I want to name this my amazing unicorn, it's going to take that and replace anywhere it finds my custom template here, that solution directories files anywhere with my special unicorn or amazing. 22 00:04:02,000 --> 00:04:10,000 I don't know what I said. And then you have tags like language and type. This is a project template for C shop and basically that's it. 23 00:04:10,000 --> 00:04:24,000 Now, once I save that, this is technically ready to be used. I can go ahead here and I'm already in the directory of this template and I can do dot net new double hyphen install and I can other point to a new get package. 24 00:04:24,000 --> 00:04:34,000 Or I can point to directory and I'm going to use the current directory. So I'm going to say dot here and I'm going to install this template and now as you can see my custom template has been installed. 25 00:04:34,000 --> 00:04:52,000 I can go ahead and do a dot new list and I can see my custom template here and I can use that. In fact, I can do that here. I can say dot net new my custom template and I'm going to give it a name my amazing unicorn. 26 00:04:52,000 --> 00:05:08,000 And here you go. This has created the project and I go ahead and show you that this was actually made and let's load it up in writer. There you go project created and it has replaced all the namespaces, all the folder structure, even the launch settings.json here. 27 00:05:08,000 --> 00:05:27,000 It has been replaced or even in the startup.cs where you configure the swagger support here, it replaced that as well and also here. So it is a very intuitive and very nice by default. Now this can actually also exist in your ID writer, for example, if you go new will allow you to load more templates and I can 28 00:05:27,000 --> 00:05:44,000 install a template from a location. So I'm going to go to that template path over here and I'm going to point at the very top level where my template.config is. I'm going to say select. So if I do a reload, it's at the very bottom and I can go here and create a project using that template. 29 00:05:44,000 --> 00:06:06,000 Now, how do we extend that? Because let's say I want to make, I don't know, maybe the target framework configurable. I want the user to specify .NET 6 or .NET 5. Now that would mean that things like implicit using statements or maybe file scope namespaces can't be dealt with, but I'm going to show you how you can do that in a second. 30 00:06:06,000 --> 00:06:19,000 First, let's just focus on parameterizing this bit, the .NET 6, the target framework. How do we do that? Well, let's go here. So the ultimate goal is to have a parameter for this property. 31 00:06:19,000 --> 00:06:30,000 The first thing we want to do is we want to create symbols. So I'm going to go ahead and say symbols here and these symbols can be many things. We're going to use them for parameters. It's very extensible. 32 00:06:30,000 --> 00:06:39,000 The first thing I want to say is I'm going to give the name of the parameter I want. So in my case, it's framework. And I'm going to say that this parameter is of type parameter. 33 00:06:39,000 --> 00:06:48,000 And then I'm going to give it a description just to communicate what this is supposed to represent. So I'm going to say the target framework for the project. 34 00:06:48,000 --> 00:06:59,000 Then I'm going to specify the data type for this, because this can be a text, this can be numeric, but we want this to be, well, effectively drop down, but we call that choice here. So we want it to be a choice. 35 00:06:59,000 --> 00:07:08,000 And we're going to list the choices that we make available to the user. So this is an array of objects. And we have a choice entry here. 36 00:07:08,000 --> 00:07:25,000 And this, the default one is 6.0. We might as well add the other choice, which is 5.0, right? So we have that. And then why don't we just also add a default value for this? And in our case, it will be next to 6.0 because it's LTS. 37 00:07:25,000 --> 00:07:36,000 And also, we want to say what this is supposed to replace in our code. So this replaces. And here's where we specify text that will be identified in the template and replaced with that choice. 38 00:07:36,000 --> 00:07:43,000 So since this is representing target framework, I'm going to go ahead and delete that and use this angle bracket syntax, which is what I prefer. 39 00:07:43,000 --> 00:08:00,000 But maybe it's not too safe for you. Basically, you want something that can only exist in that single location or anywhere you want it replaced. If I was just used this without the angle brackets, then both this, this, and also this would be replaced with the new value. 40 00:08:00,000 --> 00:08:10,000 So we're going to use the syntax and paste it here. And now what this will do is it will detect that and replace. And in fact, since this is a local template, I don't have to update anything. 41 00:08:10,000 --> 00:08:28,000 I can go back to Rider. And if I do new and I go to the template, now I can select from the dropdown, the choice I just added. And in the CLI, if I do the help command, so dot net new, the name of our template, my custom template, double-help. 42 00:08:28,000 --> 00:08:44,000 I can now see that this has the framework parameter added. Now, replacing is one thing. And replacing works the same with other parameters as well. If you wanted to have a text replaced, maybe for a key or something or some other piece of name or some copyright, you could totally use the same syntax. 43 00:08:44,000 --> 00:08:59,000 We'll no longer be choice. However, you could actually completely remove this. But what I want to do is I'm going to create a parameter based on whether I want to have swagger support. So I'm going to say enable swagger support here. And I'm going to create a second parameter. 44 00:08:59,000 --> 00:09:16,000 I'm going to copy that for descriptions. I'm going to say enable swagger support for the project. Why not? And then have a data type, which is bull, because that's either true or false. And let's say that the default value here is true. 45 00:09:16,000 --> 00:09:26,000 So by default, we enable it. Now, how do we use this parameter in our code? Let me show you. We can go here and start up.cs. And I do understand that this syntax is a bit weird. 46 00:09:26,000 --> 00:09:37,000 So please follow. First, you want to find where you actually want this if statement to start. And you say at star hash if, and then you specify the parameter. 47 00:09:37,000 --> 00:09:49,000 And then where you want it to end, like here, you're going to say hash and if star and at, that's the syntax. I know it's a bit weird. It is what it is. 48 00:09:49,000 --> 00:10:02,000 And then we go back here and we do the same for the swagger bit in the bottom here and here. And now if I do a dot net help, I can get both framework and enable swagger support here. 49 00:10:02,000 --> 00:10:11,000 And I can use that. I can say dot net new and I can give it the name, which is my custom template here. And then I'm going to say, oh, and this is a new name. 50 00:10:11,000 --> 00:10:27,000 Test two or just project without swagger, let's say. And then I can specify capital F for framework. I wanted to be net 6.0 and capital E, or you can have double capital and the full parameter name here. 51 00:10:27,000 --> 00:10:35,000 And then false. So don't enable swagger support. And if I do that, this created the project. So let's go ahead and take a look at that. 52 00:10:35,000 --> 00:10:44,000 And as you can see here, the project was created successfully without swagger support, just like that. Now, how do we take this template even further? 53 00:10:44,000 --> 00:10:55,000 Well, let's say I don't want to include conditionally some files or do include them. For example, let's say I don't want to include the app settings dot development dot JSON by default. 54 00:10:55,000 --> 00:11:02,000 How do I do that? Well, I can go here and add a parameter for that. So I'm going to say include dev app settings. 55 00:11:02,000 --> 00:11:17,000 And it's still going to be like a Boolean parameter here. So I'm going to effectively copy all that and replace it or parameters ads app settings dot development dot JSON, which is this file over here. 56 00:11:17,000 --> 00:11:25,000 Let me just make sure I passed this correctly. Yes, I did. So by default, let's say yes, but you have the option to exclude it. How do we do that? 57 00:11:25,000 --> 00:11:35,000 Well, outside of this symbols area, we can go and say sources. And this is an array. And we're going to have conditions for our sources, which is a source files. 58 00:11:35,000 --> 00:11:46,000 So what I want to have is an object in here. And I'm going to call that modifiers. And these are an array of things. So the first object in the array and actually the only for this demo will be a condition. 59 00:11:46,000 --> 00:11:56,000 And the condition is in this parentheses syntax, when not include dev app settings. So when this is basically false, then exclude. 60 00:11:56,000 --> 00:12:06,000 And we're going to exclude a file here by default. This is an array, but we only want to do one. So I'm going to say my dot custom dot template. 61 00:12:06,000 --> 00:12:16,000 So we're using the pre-chains syntax here. And then a false slash app settings dot development dot JSON. So when this is false, it will not include that file. 62 00:12:16,000 --> 00:12:24,000 Let's go ahead and try this. If I do help again, you can see that we now have this include dev app settings. So I'm going to go ahead and use the previous command. 63 00:12:24,000 --> 00:12:40,000 Change the name project without dev app settings, roles of the tongue. And, you know, leave maybe this to true and say, I, which stands for include dev app settings falls. So don't include this. 64 00:12:40,000 --> 00:12:53,000 So let's make that project project was created. Let's go back and see it. And as you can see in here, this did not include the app settings dot development dot JSON because we excluded it through the template. 65 00:12:53,000 --> 00:13:05,000 Now, this just scratches the surface of what you can actually do with this template engine. So for that reason, I'm going to leave in the description the documentation in case you want to go and extend it even further, but this should take you quite a long way. 66 00:13:05,000 --> 00:13:14,000 Now, how do you actually package this up? Because you can share this with other people. You can upload it in New York and allow people to use it. 67 00:13:14,000 --> 00:13:25,000 In fact, in here is a built-in functionality called dot net new search, where you can specify parameter. Let's say search on the react. 68 00:13:25,000 --> 00:13:40,000 And this will go hit new get and search for things or templates matching that thing. Net core react, SP CRA and I can install all these by pointing to that new package, just by name. 69 00:13:40,000 --> 00:13:49,000 So that's awesome. But how do you make your own? Well, actually, all you need is a CS project looking like this. Now, this is a specialty approach. 70 00:13:49,000 --> 00:13:57,000 This is specific to your template. It is package type template. You can specify the version, the package ID, which is how you're going to upload it. 71 00:13:57,000 --> 00:14:07,000 Then, you know, your usual title, author description, and then your tags. The target framework doesn't really matter. And then you want to exclude some specific things and include some others here. 72 00:14:07,000 --> 00:14:21,000 But you can take that as a template and use it yourself. Now, where this is located is very important. You want to have this folder structure here at the very top where you have like your templates here, and then you have these templates folder. 73 00:14:21,000 --> 00:14:29,000 So you want to have it here and call it whatever you want. You can call it my amazing templates dot CS project. 74 00:14:29,000 --> 00:14:38,000 But the reason why you need that is because you can actually run a dot net pack on that level and package up your new package. 75 00:14:38,000 --> 00:14:45,000 The way you would do that is you got the very top where you have the templates and the CS project right here and do a dot net pack. 76 00:14:45,000 --> 00:14:54,000 And this would run a new package engine and it will create you a new package file that you can now use and upload to you get and share with other people. 77 00:14:54,000 --> 00:14:57,000 Well, that's all I have for you for this video. Thank you very much for watching. 78 00:14:57,000 --> 00:15:03,000 Special thanks to my patreons for making this video possible. If you want to support my as well, you're going to find a link in the description down below. 79 00:15:03,000 --> 00:15:10,000 Leave a like if you like this video. Subscribe if you like this and ring the bell as well. And I'll see you in the next video. Keep coding.