WEBVTT

1
00:00:00.120 --> 00:00:04.040
<v Speaker 1>So have you ever stopped to think about command line interfaces,

2
00:00:04.120 --> 00:00:06.639
<v Speaker 1>even if maybe you didn't quite realize you were using one.

3
00:00:06.759 --> 00:00:08.759
<v Speaker 2>Yeah, I mean think about it every time you type

4
00:00:08.800 --> 00:00:09.640
<v Speaker 2>get commit right.

5
00:00:09.560 --> 00:00:11.720
<v Speaker 1>Right, or launch a Docker container.

6
00:00:11.400 --> 00:00:15.080
<v Speaker 2>Exactly, or even when your computer updates using things like

7
00:00:15.160 --> 00:00:18.480
<v Speaker 2>apped on Linux or brew on macOS. That's all CLI

8
00:00:18.879 --> 00:00:19.440
<v Speaker 2>and get this.

9
00:00:19.679 --> 00:00:23.519
<v Speaker 1>Even huge graphical apps like say chat GPT often have

10
00:00:23.600 --> 00:00:27.800
<v Speaker 1>these powerful CLI tools working behind the scenes for automation

11
00:00:28.519 --> 00:00:29.480
<v Speaker 1>advanced control.

12
00:00:29.640 --> 00:00:32.600
<v Speaker 2>It's pretty amazing, isn't it. They really are everywhere, They

13
00:00:32.640 --> 00:00:36.399
<v Speaker 2>truly are. It's fascinating. Really, these tools are just incredibly

14
00:00:36.439 --> 00:00:40.320
<v Speaker 2>omnipresent across well the whole IT landscape. And it's not

15
00:00:40.399 --> 00:00:43.439
<v Speaker 2>just developers using the dot net cli or no jscli,

16
00:00:43.600 --> 00:00:47.000
<v Speaker 2>you know, DevOps engineers they rely on them constantly. GitHub

17
00:00:47.039 --> 00:00:48.560
<v Speaker 2>cli as your debub cli.

18
00:00:48.679 --> 00:00:49.039
<v Speaker 1>Oh yeah.

19
00:00:49.079 --> 00:00:53.920
<v Speaker 2>System admins manage whole infrastructures with PowerShell, Bash, package managers

20
00:00:53.920 --> 00:00:56.479
<v Speaker 2>like Choco or wing it on Windows right, and even

21
00:00:56.600 --> 00:00:59.759
<v Speaker 2>data scientists are in on it. Scripting with Python are

22
00:01:00.079 --> 00:01:03.960
<v Speaker 2>Panda's sequel. They really do underpin so much of our

23
00:01:04.040 --> 00:01:06.120
<v Speaker 2>digital world. Kind of like efficient backbones.

24
00:01:06.400 --> 00:01:09.640
<v Speaker 1>Efficient backbones. I like that, So welcome everyone to the

25
00:01:09.680 --> 00:01:10.239
<v Speaker 1>deep dive.

26
00:01:10.799 --> 00:01:11.079
<v Speaker 2>Hello.

27
00:01:11.640 --> 00:01:14.760
<v Speaker 1>Today we're taking a bit of a shortcut to getting

28
00:01:14.920 --> 00:01:17.599
<v Speaker 1>really well informed on a topic that Okay, I might

29
00:01:17.680 --> 00:01:21.959
<v Speaker 1>sound super technical, but it's actually incredibly practical, empowering even

30
00:01:22.480 --> 00:01:25.840
<v Speaker 1>we're talking about building COLI applications with c sharp and

31
00:01:25.920 --> 00:01:29.239
<v Speaker 1>dot Net, and we're drawing some powerful insights from to

32
00:01:29.280 --> 00:01:31.959
<v Speaker 1>Johnny Belloness, who is fantastic book on the subject.

33
00:01:32.000 --> 00:01:32.879
<v Speaker 2>It's a great resource.

34
00:01:32.959 --> 00:01:35.519
<v Speaker 1>Our mission today, well, it's to unpack the core ideas,

35
00:01:35.719 --> 00:01:38.719
<v Speaker 1>some maybe unexpected benefits and the sort of step by

36
00:01:38.760 --> 00:01:42.879
<v Speaker 1>step process for creating these cross platform command line apps

37
00:01:43.319 --> 00:01:47.200
<v Speaker 1>and more importantly, why you listening right now should absolutely

38
00:01:47.280 --> 00:01:47.959
<v Speaker 1>care about.

39
00:01:47.760 --> 00:01:52.000
<v Speaker 2>This stuff into Johnny Belminsur is really an exceptional guide

40
00:01:52.000 --> 00:01:54.319
<v Speaker 2>for this. I mean over twenty one years of experience,

41
00:01:54.640 --> 00:01:57.840
<v Speaker 2>especially in dot net and Azure. Wow. Yeah, and apparently

42
00:01:57.879 --> 00:02:00.840
<v Speaker 2>he wrote his first program in quick basic when he was.

43
00:02:00.799 --> 00:02:03.400
<v Speaker 1>Just eight eight Okay, that's impressive, right.

44
00:02:03.640 --> 00:02:06.719
<v Speaker 2>So that extensive hands on background it makes them uniquely

45
00:02:06.799 --> 00:02:10.960
<v Speaker 2>qualified to explain these sometimes complex topics. And what's interesting

46
00:02:11.039 --> 00:02:14.840
<v Speaker 2>is how he uses cutting edge AI to like enhance

47
00:02:14.879 --> 00:02:17.800
<v Speaker 2>the language and clarity in his writing. Oh interesting, but

48
00:02:17.800 --> 00:02:21.199
<v Speaker 2>he ensures the actual content integrity is strictly his own.

49
00:02:21.680 --> 00:02:22.560
<v Speaker 2>It's a neat blend.

50
00:02:22.719 --> 00:02:26.080
<v Speaker 1>That is a neat blend. So okay, what does this

51
00:02:26.120 --> 00:02:28.919
<v Speaker 1>all mean for you, our listener? Why should you care

52
00:02:29.000 --> 00:02:30.400
<v Speaker 1>about CLI apps?

53
00:02:30.639 --> 00:02:34.000
<v Speaker 2>Well, they aren't just obscure tools for you know, hardcore coders.

54
00:02:34.439 --> 00:02:38.560
<v Speaker 2>They are seriously powerful productivity enhancers. They can drastically simplify

55
00:02:38.599 --> 00:02:41.319
<v Speaker 2>your life. Also, well, for one, they help you stay

56
00:02:41.319 --> 00:02:44.479
<v Speaker 2>focused less context switching. Right, you're not jumping between a

57
00:02:44.520 --> 00:02:46.319
<v Speaker 2>dozen different graphical windows all the time.

58
00:02:46.400 --> 00:02:47.800
<v Speaker 1>Okay, yeah, I feel that pain.

59
00:02:47.879 --> 00:02:51.199
<v Speaker 2>And they automate those repetitive, error prone tasks that just

60
00:02:51.240 --> 00:02:52.879
<v Speaker 2>eat up your time. And you know, they can even

61
00:02:52.879 --> 00:02:54.840
<v Speaker 2>build things like workstation profiles.

62
00:02:54.879 --> 00:02:56.960
<v Speaker 1>Workstation profiles, tell me more about that.

63
00:02:57.039 --> 00:03:01.199
<v Speaker 2>Imagine this, Instead of spending like hours annually installing and

64
00:03:01.240 --> 00:03:04.080
<v Speaker 2>configuring software for a new team member or even just

65
00:03:04.120 --> 00:03:08.919
<v Speaker 2>a fresh PC, yeah the worst, a single command could

66
00:03:08.960 --> 00:03:12.639
<v Speaker 2>potentially automate the entire setup. Curiously, Yeah, think about the

67
00:03:12.639 --> 00:03:15.759
<v Speaker 2>time and frustration saved, Whether it's just for your personal

68
00:03:15.800 --> 00:03:19.080
<v Speaker 2>workflow or for a whole organization. It's huge.

69
00:03:19.319 --> 00:03:22.000
<v Speaker 1>That is huge. So this deep dive, it's kind of

70
00:03:22.000 --> 00:03:25.800
<v Speaker 1>offering those aha moments, right, giving you a clear path

71
00:03:25.879 --> 00:03:29.120
<v Speaker 1>to understanding the how and the why these tools are so.

72
00:03:29.120 --> 00:03:32.000
<v Speaker 2>Transformative exactly a shortcut to that understanding.

73
00:03:32.039 --> 00:03:35.000
<v Speaker 1>Okay, let's unpack this first bit, then the unsung hero.

74
00:03:35.960 --> 00:03:39.080
<v Speaker 1>Why are cli apps everywhere? And what are they really

75
00:03:39.120 --> 00:03:42.280
<v Speaker 1>built on? We've touched on how widespread.

76
00:03:41.759 --> 00:03:44.520
<v Speaker 2>They are, Yeah, they're ubiquity, but it's worth.

77
00:03:44.240 --> 00:03:47.599
<v Speaker 1>Hammering home just how ingrained they are, often working silently,

78
00:03:47.680 --> 00:03:48.759
<v Speaker 1>making things stick.

79
00:03:48.560 --> 00:03:51.240
<v Speaker 2>And connecting this back to productivity. Yeah, that's where they

80
00:03:51.280 --> 00:03:52.479
<v Speaker 2>really shine, keeping.

81
00:03:52.240 --> 00:03:55.159
<v Speaker 1>You focus way less context switching exactly.

82
00:03:54.800 --> 00:03:59.479
<v Speaker 2>Every time you switch apps, email, project, tool chat, the

83
00:03:59.560 --> 00:04:02.680
<v Speaker 2>chance of getting to rail just skyrockets, you know, totally.

84
00:04:02.759 --> 00:04:06.599
<v Speaker 2>Celi tools minimize that you string together complex operations with

85
00:04:06.680 --> 00:04:11.680
<v Speaker 2>simple commands and those workstation profiles. Traditionally that meant custom

86
00:04:11.759 --> 00:04:12.960
<v Speaker 2>OS images.

87
00:04:12.840 --> 00:04:14.960
<v Speaker 1>Oh, the big clunky images.

88
00:04:15.159 --> 00:04:20.720
<v Speaker 2>Yeah, costly storage, OS updates, tool updates, human frustration. It

89
00:04:20.759 --> 00:04:23.360
<v Speaker 2>was a mess, I can imagine. But by using CLI

90
00:04:23.399 --> 00:04:27.439
<v Speaker 2>apps like PowerShell, scripts with package managers like Chocolatey or Wingt,

91
00:04:27.959 --> 00:04:31.360
<v Speaker 2>it can automate the whole setup based on user rolls.

92
00:04:31.879 --> 00:04:35.240
<v Speaker 2>Users get more autonomy, Manual installed time plummets. It's a

93
00:04:35.279 --> 00:04:40.480
<v Speaker 2>shift from manual, air prone work to automated, repeatable.

94
00:04:39.839 --> 00:04:42.319
<v Speaker 1>Processes that sounds like a massive win. I can just

95
00:04:42.439 --> 00:04:46.360
<v Speaker 1>picture the IT department breathing a collective sigh of relief. Absolutely,

96
00:04:46.639 --> 00:04:48.879
<v Speaker 1>And what's really fascinating is you said, at the heart

97
00:04:48.920 --> 00:04:52.519
<v Speaker 1>of all this sophistication, it's basically just a simple console

98
00:04:52.519 --> 00:04:53.879
<v Speaker 1>application pretty much.

99
00:04:53.959 --> 00:04:56.759
<v Speaker 2>That's the surprising truth. It provides that basic structure before

100
00:04:56.759 --> 00:04:59.519
<v Speaker 2>you start adding all the CLI bills and whistles.

101
00:04:59.560 --> 00:05:00.920
<v Speaker 1>So if you want to build these, what are the

102
00:05:01.000 --> 00:05:02.639
<v Speaker 1>essential tools? What's the starter kit?

103
00:05:02.720 --> 00:05:06.439
<v Speaker 2>Okay, your developer toolkit Visual studio Code is a huge one.

104
00:05:06.720 --> 00:05:11.079
<v Speaker 2>It's free, cross platform, super powerful, especially with all its extensions.

105
00:05:11.199 --> 00:05:12.279
<v Speaker 1>Right, the extensions make it.

106
00:05:12.319 --> 00:05:14.720
<v Speaker 2>Then you need the dot net SDK. That's crucial for

107
00:05:14.759 --> 00:05:18.160
<v Speaker 2>c shark development, the foundation for building and running dot

108
00:05:18.199 --> 00:05:22.480
<v Speaker 2>net apps. Got it and Get absolutely indispensable for version control,

109
00:05:22.560 --> 00:05:25.120
<v Speaker 2>tracking changes, collaborating. You need GET.

110
00:05:25.279 --> 00:05:28.560
<v Speaker 1>Can't live without Get any key vus code extensions you'd

111
00:05:28.560 --> 00:05:29.480
<v Speaker 1>recommend definitely.

112
00:05:29.560 --> 00:05:32.759
<v Speaker 2>The c sharp DevKit is essential now in telecode for

113
00:05:32.800 --> 00:05:36.199
<v Speaker 2>C sharp DevKit. That gives you that AI powered whole

114
00:05:36.240 --> 00:05:38.000
<v Speaker 2>line completion which is pretty.

115
00:05:37.720 --> 00:05:39.759
<v Speaker 1>Slightly oh nice.

116
00:05:39.519 --> 00:05:43.439
<v Speaker 2>And gitlans. It just makes working with get history inside

117
00:05:43.519 --> 00:05:46.360
<v Speaker 2>vs codes so much easier. Boost productivity for sure.

118
00:05:46.800 --> 00:05:49.759
<v Speaker 1>Okay, so we start with this basic console application. How

119
00:05:49.839 --> 00:05:51.639
<v Speaker 1>do we level it up? How do we go from

120
00:05:51.680 --> 00:05:55.839
<v Speaker 1>just simple text in text out to something that understands

121
00:05:55.879 --> 00:05:58.160
<v Speaker 1>more complex commands, something user friendly.

122
00:05:58.279 --> 00:06:02.000
<v Speaker 2>That's the next step, right, mastering user input beyond just

123
00:06:02.040 --> 00:06:03.839
<v Speaker 2>that raw array of argument to.

124
00:06:03.879 --> 00:06:06.160
<v Speaker 1>Get Yeah, the string arcs exactly.

125
00:06:05.759 --> 00:06:09.040
<v Speaker 2>So system dot console is your starting point. Basic interactions

126
00:06:09.160 --> 00:06:11.399
<v Speaker 2>right line and right for output, read line and read

127
00:06:11.480 --> 00:06:12.240
<v Speaker 2>key for input.

128
00:06:12.399 --> 00:06:13.360
<v Speaker 1>Standard stuff.

129
00:06:13.439 --> 00:06:16.040
<v Speaker 2>Yeah, you can even use background color and foreground color

130
00:06:16.040 --> 00:06:18.600
<v Speaker 2>for some visual feedback guide the user a bit. Oh,

131
00:06:18.639 --> 00:06:22.519
<v Speaker 2>that's and and title is useful for labeling the console window.

132
00:06:22.720 --> 00:06:24.920
<v Speaker 2>But just a heads up. It's only visible in like

133
00:06:25.240 --> 00:06:27.680
<v Speaker 2>external terminals, not the integrated one in vs code.

134
00:06:27.720 --> 00:06:30.319
<v Speaker 1>Usually good to know. But okay, what if your CLI

135
00:06:30.399 --> 00:06:33.439
<v Speaker 1>app is doing something important, something long running, and the

136
00:06:33.560 --> 00:06:35.959
<v Speaker 1>user just hits ctrol plus.

137
00:06:35.720 --> 00:06:38.040
<v Speaker 2>C ah the panic button.

138
00:06:38.240 --> 00:06:40.319
<v Speaker 1>Right, You can't just let it crash if it's saving

139
00:06:40.399 --> 00:06:42.279
<v Speaker 1>data or cleaning up resources, can you?

140
00:06:42.319 --> 00:06:47.000
<v Speaker 2>No? Absolutely not, Especially with sophisticated apps. You risk data loss,

141
00:06:47.240 --> 00:06:51.240
<v Speaker 2>corrupted state. It's bad news. That's where the cancel keypress

142
00:06:51.240 --> 00:06:52.040
<v Speaker 2>event is crucial.

143
00:06:52.199 --> 00:06:53.560
<v Speaker 1>Cancel keypress it gets.

144
00:06:53.360 --> 00:06:56.639
<v Speaker 2>Triggered by cutrol plus c or ctrl plus break and

145
00:06:56.680 --> 00:06:59.160
<v Speaker 2>if you handle that event, your application gets a chance

146
00:06:59.160 --> 00:07:02.079
<v Speaker 2>to do crucial clean before it exits, like what like

147
00:07:02.240 --> 00:07:05.680
<v Speaker 2>saving at state, logging out of services, maybe closing database

148
00:07:05.680 --> 00:07:09.800
<v Speaker 2>connections gracefully. It prevents those abrupt crashes and lost data,

149
00:07:10.240 --> 00:07:12.959
<v Speaker 2>ensures a clean shutdown, vital for reliability.

150
00:07:13.399 --> 00:07:16.480
<v Speaker 1>Okay, that makes sense for basic console apps. But real

151
00:07:16.519 --> 00:07:19.040
<v Speaker 1>cli apps, the ones we use daily, they have named

152
00:07:19.079 --> 00:07:22.839
<v Speaker 1>parameters right, and subcommands. It's much clearer than just trying

153
00:07:22.839 --> 00:07:24.920
<v Speaker 1>to remember the order of arguments in a raw string

154
00:07:25.040 --> 00:07:26.199
<v Speaker 1>array exactly.

155
00:07:26.480 --> 00:07:29.000
<v Speaker 2>That's the big leap in user friendliness. Instead of my

156
00:07:29.079 --> 00:07:30.759
<v Speaker 2>climb RG one ARC two and hoping you got the

157
00:07:30.839 --> 00:07:31.240
<v Speaker 2>order right?

158
00:07:31.319 --> 00:07:32.439
<v Speaker 1>Yeah, what was R two again?

159
00:07:32.600 --> 00:07:37.360
<v Speaker 2>Right, you get a much more powerful discoverable interface named parameters, switches,

160
00:07:37.560 --> 00:07:43.319
<v Speaker 2>subcommands like a bookmark, parklink, ad name my blog, you're lolo,

161
00:07:43.560 --> 00:07:46.360
<v Speaker 2>hgtps dot my blog dot com.

162
00:07:46.480 --> 00:07:49.680
<v Speaker 1>Ah Okay, much clearer, way clearer.

163
00:07:49.680 --> 00:07:52.519
<v Speaker 2>And ps users understand what's expected, what the parameters mean,

164
00:07:52.720 --> 00:07:55.839
<v Speaker 2>how to provide them correctly. Cuts down on guesswork and

165
00:07:55.959 --> 00:07:56.920
<v Speaker 2>airs massively.

166
00:07:57.040 --> 00:07:59.959
<v Speaker 1>So if we want to build these modern intuitive cli

167
00:08:00.120 --> 00:08:02.680
<v Speaker 1>in dot net, what's the recommended library? Is there a

168
00:08:02.720 --> 00:08:04.560
<v Speaker 1>go to that Microsoft pushes.

169
00:08:04.439 --> 00:08:06.920
<v Speaker 2>Absolutely for dot net. System dot command line is the one.

170
00:08:06.959 --> 00:08:11.240
<v Speaker 2>It's a robust dot Net Foundation project actively maintained by Microsoft.

171
00:08:11.319 --> 00:08:13.439
<v Speaker 1>Okay, system dot command line. And why is it better

172
00:08:13.480 --> 00:08:15.560
<v Speaker 1>than say, older ways of doing this, Well.

173
00:08:15.399 --> 00:08:17.720
<v Speaker 2>The real insight is how it shifts your thinking. You

174
00:08:17.759 --> 00:08:20.959
<v Speaker 2>move from manually parsing that messy command line input which

175
00:08:21.000 --> 00:08:24.560
<v Speaker 2>is always a pain, to declaratively building intelligent interfaces. It

176
00:08:24.639 --> 00:08:27.279
<v Speaker 2>uses this modern builder pattern. Think of it like defining

177
00:08:27.319 --> 00:08:30.439
<v Speaker 2>your commands and options in a structured, readable way, building

178
00:08:30.480 --> 00:08:32.000
<v Speaker 2>with Lego bricks, almost.

179
00:08:31.800 --> 00:08:33.120
<v Speaker 1>Lego bricks for commands.

180
00:08:33.200 --> 00:08:36.360
<v Speaker 2>I like it, yeah, And it's not just syntax. It

181
00:08:36.399 --> 00:08:40.960
<v Speaker 2>makes your CLI inherently more robust, user friendly, and maintainable

182
00:08:41.039 --> 00:08:43.919
<v Speaker 2>right from the start. It helps eliminate common input errors

183
00:08:43.919 --> 00:08:44.759
<v Speaker 2>before they even happen.

184
00:08:44.840 --> 00:08:46.200
<v Speaker 1>And it comes with built in goodies.

185
00:08:46.320 --> 00:08:50.279
<v Speaker 2>Oh yeah, fantastic built in features. Command hierarchies you know

186
00:08:50.360 --> 00:08:53.840
<v Speaker 2>like get has clone an ad automatic tab completion which

187
00:08:54.000 --> 00:08:57.960
<v Speaker 2>users love. Even version number retrieval like version makes your

188
00:08:57.960 --> 00:09:00.159
<v Speaker 2>CLI feel professional right out of the box.

189
00:09:00.320 --> 00:09:01.679
<v Speaker 1>How does it work? Structurally?

190
00:09:02.039 --> 00:09:04.399
<v Speaker 2>You define a root command that's the main entry point,

191
00:09:04.679 --> 00:09:07.799
<v Speaker 2>then you add subcommands and these option t objects. The

192
00:09:07.879 --> 00:09:11.279
<v Speaker 2>TA means they support various data types, strings, integers, booleans,

193
00:09:11.360 --> 00:09:14.799
<v Speaker 2>file paths, you name it, plus aliases makes it super

194
00:09:14.799 --> 00:09:15.960
<v Speaker 2>powerful and easy to use.

195
00:09:16.080 --> 00:09:18.960
<v Speaker 1>That does sound powerful, but for someone maybe used to

196
00:09:19.000 --> 00:09:22.600
<v Speaker 1>older libraries. What's the biggest mental shift with this builder pattern?

197
00:09:22.720 --> 00:09:24.080
<v Speaker 1>Is it a steep learning curve?

198
00:09:24.360 --> 00:09:28.159
<v Speaker 2>You know, it's surprisingly intuitive once you click with the concept.

199
00:09:28.679 --> 00:09:31.720
<v Speaker 2>The main shift is going from imperatively grabbing stuff from

200
00:09:31.840 --> 00:09:33.600
<v Speaker 2>ARGs and then manually checking.

201
00:09:33.360 --> 00:09:35.679
<v Speaker 1>It right writing lots of if statements.

202
00:09:35.440 --> 00:09:39.440
<v Speaker 2>To declaratively defining what your command expects. You basically tell

203
00:09:39.480 --> 00:09:41.679
<v Speaker 2>system doc command like hey, I need a string here

204
00:09:41.679 --> 00:09:44.600
<v Speaker 2>and it's required, or this is an integer it's optional,

205
00:09:45.039 --> 00:09:48.039
<v Speaker 2>and it handles the parsing and the basic validation for you.

206
00:09:48.240 --> 00:09:50.960
<v Speaker 1>Ah, so you focus more on the actual logic of

207
00:09:50.960 --> 00:09:51.720
<v Speaker 1>the command.

208
00:09:51.559 --> 00:09:53.720
<v Speaker 2>Exactly, not the tedious parsing plumbing.

209
00:09:54.200 --> 00:09:57.519
<v Speaker 1>Excellent point. So building on that, how do we make

210
00:09:57.559 --> 00:10:00.480
<v Speaker 1>sure the app is truly robust, especially with with user

211
00:10:00.559 --> 00:10:03.000
<v Speaker 1>input and how do we manage data safely?

212
00:10:03.320 --> 00:10:06.799
<v Speaker 2>Yeah, that leads right into proper input validation. You control

213
00:10:06.840 --> 00:10:11.200
<v Speaker 2>the input using properties on those options like is required

214
00:10:11.200 --> 00:10:14.080
<v Speaker 2>for mandatory ones, the user has to provide it, okay,

215
00:10:14.200 --> 00:10:16.720
<v Speaker 2>makes sense? Or sometimes you want to accept multiple values

216
00:10:16.720 --> 00:10:19.679
<v Speaker 2>for one option, right, like adding several bookmarks at once. Yeah,

217
00:10:19.759 --> 00:10:22.799
<v Speaker 2>for that argumentarity one or more is super.

218
00:10:22.559 --> 00:10:24.759
<v Speaker 1>Flexible argumentarity got it.

219
00:10:25.080 --> 00:10:27.919
<v Speaker 2>And for really specific checks, say you want to assure

220
00:10:27.919 --> 00:10:32.080
<v Speaker 2>a bookmark URL only points to like an internal corporate domain,

221
00:10:32.840 --> 00:10:34.960
<v Speaker 2>you can use add validator to hook in your own

222
00:10:35.320 --> 00:10:38.480
<v Speaker 2>custom validation logic. This way, bad data just doesn't even

223
00:10:38.480 --> 00:10:39.799
<v Speaker 2>get into your application flow.

224
00:10:40.080 --> 00:10:43.919
<v Speaker 1>That's smart, preventing problems early. What about dealing with files?

225
00:10:44.480 --> 00:10:47.679
<v Speaker 1>Lots of CLI tools process files or output to them.

226
00:10:48.039 --> 00:10:49.519
<v Speaker 1>How does the book approach that.

227
00:10:49.519 --> 00:10:52.840
<v Speaker 2>That's a super common and critical task. Yeah. CLI apps

228
00:10:52.879 --> 00:10:54.679
<v Speaker 2>often read from files or write.

229
00:10:54.480 --> 00:10:58.039
<v Speaker 1>Results like import texport or processing logs exactly.

230
00:10:58.120 --> 00:11:01.320
<v Speaker 2>So you can use file info options and combine those

231
00:11:01.360 --> 00:11:04.480
<v Speaker 2>with validators like legal file names only just to make

232
00:11:04.480 --> 00:11:07.080
<v Speaker 2>sure the file them is valid for the OS and existing.

233
00:11:06.759 --> 00:11:09.480
<v Speaker 1>Only ah, to make sure the input file actually exists

234
00:11:09.480 --> 00:11:10.519
<v Speaker 1>before you try reading it.

235
00:11:10.679 --> 00:11:14.399
<v Speaker 2>Precisely. It prevents those nasty file not found exception errors downstream.

236
00:11:14.879 --> 00:11:18.279
<v Speaker 2>This makes things like back up and restore features really robust,

237
00:11:18.639 --> 00:11:22.200
<v Speaker 2>like the bookmark example in the book uses Jason importexport,

238
00:11:22.440 --> 00:11:24.080
<v Speaker 2>or just sharing data between systems.

239
00:11:24.279 --> 00:11:27.080
<v Speaker 1>Okay, so validation helps a lot, but Even with the

240
00:11:27.120 --> 00:11:30.879
<v Speaker 1>best checks, things can still go wrong. Right, Software is complex?

241
00:11:31.240 --> 00:11:33.840
<v Speaker 1>What's the safety net for unexpected errors? And how do

242
00:11:33.919 --> 00:11:36.200
<v Speaker 1>we actually see what our app is doing? Especially if

243
00:11:36.200 --> 00:11:37.279
<v Speaker 1>something does go wrong.

244
00:11:37.600 --> 00:11:40.519
<v Speaker 2>You're absolutely right, No code is perfect. So error handling

245
00:11:40.559 --> 00:11:44.080
<v Speaker 2>and CLI apps it follows standard best practices pretty much

246
00:11:44.080 --> 00:11:45.120
<v Speaker 2>like any other app type.

247
00:11:45.320 --> 00:11:47.200
<v Speaker 1>So try catch blocks, yep.

248
00:11:47.039 --> 00:11:50.080
<v Speaker 2>Try cash finally is your friend, But the key is

249
00:11:50.159 --> 00:11:53.720
<v Speaker 2>catching specific exceptions before the generic exception.

250
00:11:54.000 --> 00:11:54.480
<v Speaker 1>Why is that.

251
00:11:54.440 --> 00:11:58.200
<v Speaker 2>Important because it lets you give much better, more specific

252
00:11:58.240 --> 00:12:01.840
<v Speaker 2>feedback to the user. Catching a file not found exception

253
00:12:02.200 --> 00:12:05.639
<v Speaker 2>and saying, hey, that file doesn't exist is way more

254
00:12:05.639 --> 00:12:08.960
<v Speaker 2>helpful than just a generic oops, an error occurred. Right.

255
00:12:09.240 --> 00:12:12.159
<v Speaker 1>Users hate generic errors exactly.

256
00:12:12.039 --> 00:12:15.080
<v Speaker 2>And creating your own custom exceptions like maybe a user

257
00:12:15.120 --> 00:12:18.279
<v Speaker 2>already exists exception for the bookmark app makes your code

258
00:12:18.320 --> 00:12:21.559
<v Speaker 2>clearer and lets you handle specific problem types cleanly.

259
00:12:21.759 --> 00:12:23.120
<v Speaker 1>And beyond just reacting to.

260
00:12:23.159 --> 00:12:28.960
<v Speaker 2>Errors, defensive programming is key, validating inputs up front, enforcing preconditions,

261
00:12:29.360 --> 00:12:32.159
<v Speaker 2>basically trying to prevent errors before they even happen. That's

262
00:12:32.159 --> 00:12:33.159
<v Speaker 2>your first line of defense.

263
00:12:33.240 --> 00:12:36.399
<v Speaker 1>Okay, so error handling helps us recover, but how do

264
00:12:36.440 --> 00:12:38.879
<v Speaker 1>we understand why errors happen? Or just track what the

265
00:12:38.919 --> 00:12:41.360
<v Speaker 1>app is doing over time, especially in production.

266
00:12:41.600 --> 00:12:48.879
<v Speaker 2>Ah. That's where structured logging is absolutely essential for diagnostics, monitoring, debugging, crucial.

267
00:12:48.519 --> 00:12:50.039
<v Speaker 1>Stuff, and Jason is good for that.

268
00:12:50.480 --> 00:12:55.120
<v Speaker 2>Jason is excellent. It's machine readable, lightweight, easily parsed by

269
00:12:55.159 --> 00:12:58.639
<v Speaker 2>log management tools like Splunk or elastic stack.

270
00:12:58.799 --> 00:13:02.080
<v Speaker 1>Makes sense. Any recommend library for dot net sera, Loog

271
00:13:02.240 --> 00:13:03.159
<v Speaker 1>is fantastic.

272
00:13:03.399 --> 00:13:06.799
<v Speaker 2>It's a really powerful dot net logging library that excels

273
00:13:06.840 --> 00:13:08.000
<v Speaker 2>as structured logging.

274
00:13:08.240 --> 00:13:11.000
<v Speaker 1>Structured logging what does that mean exactly?

275
00:13:11.159 --> 00:13:13.840
<v Speaker 2>Instead of just logging a plain text message, you log

276
00:13:13.879 --> 00:13:17.440
<v Speaker 2>events with rich typed data attached. So you might log

277
00:13:17.480 --> 00:13:21.960
<v Speaker 2>an order placed event with properties like ordered customer, total amount.

278
00:13:21.759 --> 00:13:24.399
<v Speaker 1>Ah okay, so you can easily search and filter later

279
00:13:24.519 --> 00:13:25.600
<v Speaker 1>based on those properties.

280
00:13:25.600 --> 00:13:30.279
<v Speaker 2>Precisely makes analyzing logs incredibly powerful. Sarah. Loog has various

281
00:13:30.320 --> 00:13:35.080
<v Speaker 2>sinks destinations for your logs, console files, data bases, cloud services,

282
00:13:35.320 --> 00:13:37.559
<v Speaker 2>tons of options and you can figure it yeah. Usually

283
00:13:37.559 --> 00:13:40.320
<v Speaker 2>in appsettings dot Jason, you can set minimum log levels

284
00:13:40.360 --> 00:13:43.120
<v Speaker 2>like only show warning and above and production to reduce noise.

285
00:13:43.399 --> 00:13:45.919
<v Speaker 2>You can enrich logs with context like the machine name

286
00:13:46.039 --> 00:13:49.679
<v Speaker 2>or thread id, which is super helpful for debugging tricky.

287
00:13:49.399 --> 00:13:51.799
<v Speaker 1>Issues id yeah for concurrent stuff.

288
00:13:51.519 --> 00:13:55.600
<v Speaker 2>Definitely, And one crucial thing always remember to call log

289
00:13:55.679 --> 00:13:59.360
<v Speaker 2>dot close and flesh when your app exits. It ensures

290
00:13:59.360 --> 00:14:01.879
<v Speaker 2>that any offered log messages are written out before the

291
00:14:01.919 --> 00:14:05.480
<v Speaker 2>application shuts down completely. Guarantees you don't lose those last

292
00:14:05.480 --> 00:14:07.879
<v Speaker 2>few vital log entries, especially if the app crashes.

293
00:14:07.919 --> 00:14:10.679
<v Speaker 1>Good tip. Okay, so we've covered the nuts and bolts

294
00:14:10.840 --> 00:14:15.600
<v Speaker 1>robustness error handling logging, but let's be real. Staring at

295
00:14:15.639 --> 00:14:18.519
<v Speaker 1>a black screen with plain white text, it can be

296
00:14:18.600 --> 00:14:19.799
<v Speaker 1>a bit well dry.

297
00:14:20.039 --> 00:14:22.039
<v Speaker 2>Uh huh yeah, even for tech pros.

298
00:14:22.120 --> 00:14:24.519
<v Speaker 1>So if we want users to actually enjoy using our

299
00:14:24.519 --> 00:14:27.279
<v Speaker 1>CLI tools, maybe even love them, how do we go

300
00:14:27.360 --> 00:14:30.600
<v Speaker 1>beyond just basic text? How do we make the experience

301
00:14:30.679 --> 00:14:33.679
<v Speaker 1>interactive and dare I say, visually engaging?

302
00:14:33.799 --> 00:14:36.320
<v Speaker 2>This is where a library like spector Console becomes an

303
00:14:36.360 --> 00:14:37.639
<v Speaker 2>absolute game changer.

304
00:14:38.039 --> 00:14:41.120
<v Speaker 1>Seriously, Specter Dot Console, okay, tell me more.

305
00:14:41.200 --> 00:14:43.879
<v Speaker 2>It goes way beyond just simple color text. It lets

306
00:14:43.919 --> 00:14:46.279
<v Speaker 2>you render really visually appealing elements right there in.

307
00:14:46.240 --> 00:14:47.919
<v Speaker 1>The terminal, Like what kind of elements?

308
00:14:48.039 --> 00:14:51.399
<v Speaker 2>Think ASKI art banners using figlet for a cool startup screen.

309
00:14:51.519 --> 00:14:55.399
<v Speaker 2>Nice emojis to add a bit of personality, rich markup

310
00:14:55.440 --> 00:14:59.279
<v Speaker 2>for bowlding, text specific colors, even clickable links in terminals

311
00:14:59.279 --> 00:14:59.799
<v Speaker 2>that support it.

312
00:15:00.080 --> 00:15:01.240
<v Speaker 1>Couple links in the terminal.

313
00:15:01.320 --> 00:15:05.480
<v Speaker 2>Wow. Yeah, it's basically an enhanced alternative to the standard

314
00:15:05.480 --> 00:15:10.360
<v Speaker 2>system dot console, better functionality, cross platform compatibility, and a

315
00:15:10.399 --> 00:15:13.840
<v Speaker 2>whole suite of interactive components. Yeah. It turns that drab

316
00:15:13.919 --> 00:15:16.080
<v Speaker 2>terminal into like a dynamic canvas.

317
00:15:16.159 --> 00:15:17.200
<v Speaker 1>Okay, dynamic canvas.

318
00:15:17.279 --> 00:15:17.639
<v Speaker 2>I like that.

319
00:15:17.720 --> 00:15:19.320
<v Speaker 1>So it looks good, But how does it help with

320
00:15:19.399 --> 00:15:24.279
<v Speaker 1>actual user interaction making it feel dynamic? Not just pretty?

321
00:15:24.600 --> 00:15:27.679
<v Speaker 2>Great question? It excels there too. You can create dynamic

322
00:15:27.759 --> 00:15:31.440
<v Speaker 2>experiences like selection prompts.

323
00:15:31.480 --> 00:15:32.799
<v Speaker 1>Selection prompts yeah.

324
00:15:32.639 --> 00:15:35.039
<v Speaker 2>Where the user sees a list of choices and can

325
00:15:35.159 --> 00:15:38.399
<v Speaker 2>navigate using arrow keys and hit enter, much nicer than

326
00:15:38.440 --> 00:15:41.600
<v Speaker 2>typing out an option number. Oh definitely, or live progress

327
00:15:41.639 --> 00:15:44.519
<v Speaker 2>bars for long running operations. Gives the user real time

328
00:15:44.559 --> 00:15:46.519
<v Speaker 2>feedback that something is actually happening.

329
00:15:46.600 --> 00:15:50.639
<v Speaker 1>That's essential for longer tasks, avoids the is it frozen feeling.

330
00:15:50.519 --> 00:15:54.159
<v Speaker 2>Exactly, and it's great for presenting complex data clearly using

331
00:15:54.200 --> 00:15:55.519
<v Speaker 2>things like tree views.

332
00:15:55.720 --> 00:15:58.480
<v Speaker 1>Tree views like for hierarchical data yep.

333
00:15:59.000 --> 00:16:02.679
<v Speaker 2>Imagine organizing bookmarks by category in a nice tree structure

334
00:16:02.799 --> 00:16:05.960
<v Speaker 2>right in the terminal output makes complex information much more

335
00:16:06.000 --> 00:16:10.080
<v Speaker 2>digestible and honestly more engaging for the user. It really

336
00:16:10.120 --> 00:16:13.320
<v Speaker 2>transforms that passive display into an active conversation.

337
00:16:13.679 --> 00:16:17.879
<v Speaker 1>That sounds incredibly powerful for making CLIs more approachable, especially

338
00:16:17.879 --> 00:16:22.399
<v Speaker 1>for maybe less technical users. Yeah, but is there a downside?

339
00:16:22.559 --> 00:16:24.919
<v Speaker 1>Can too much interactivity be a bad thing?

340
00:16:25.039 --> 00:16:28.279
<v Speaker 2>Sometimes you've hit on a really crucial point there. Balance

341
00:16:28.440 --> 00:16:31.759
<v Speaker 2>interactivity is fantastic for human users, no doubt, but you

342
00:16:31.840 --> 00:16:32.840
<v Speaker 2>have to use it wisely.

343
00:16:33.120 --> 00:16:33.600
<v Speaker 1>Why is that?

344
00:16:34.000 --> 00:16:37.600
<v Speaker 2>Think about automation. What if your CLI tool is also

345
00:16:37.679 --> 00:16:41.519
<v Speaker 2>meant to be used in say a CICD pipeline.

346
00:16:41.039 --> 00:16:45.480
<v Speaker 1>AH continuous integration, continuous delivery, automated builds and deployment.

347
00:16:45.720 --> 00:16:50.080
<v Speaker 2>Right, those automated processes can't answer interactive prompts. An unexpected

348
00:16:50.120 --> 00:16:51.639
<v Speaker 2>prompt would just hang the pipeline.

349
00:16:51.720 --> 00:16:53.600
<v Speaker 1>Okay, so that's a problem. How do you handle that?

350
00:16:53.759 --> 00:16:56.200
<v Speaker 2>You need to provide a non interactive mode. A common

351
00:16:56.240 --> 00:16:58.919
<v Speaker 2>pattern is to add an interactive flag or option.

352
00:16:59.000 --> 00:17:01.000
<v Speaker 1>So humans can run it with interactive to get the

353
00:17:01.080 --> 00:17:02.879
<v Speaker 1>nice prompts in progress bars.

354
00:17:02.919 --> 00:17:06.200
<v Speaker 2>Exactly, and the automated scripts run it without that flag,

355
00:17:06.279 --> 00:17:10.359
<v Speaker 2>so it just executes non interactively. Maybe using default values

356
00:17:10.480 --> 00:17:12.400
<v Speaker 2>or taking all input via parameters.

357
00:17:12.519 --> 00:17:15.279
<v Speaker 1>That makes sense. Designed for different ways people and machines

358
00:17:15.359 --> 00:17:15.880
<v Speaker 1>will use it.

359
00:17:16.039 --> 00:17:20.079
<v Speaker 2>Flexibility precisely, it's about designing for different consumption patterns.

360
00:17:20.160 --> 00:17:23.759
<v Speaker 1>Okay, So let's say our app is growing, We're adding features, interactivity,

361
00:17:23.839 --> 00:17:26.759
<v Speaker 1>maybe talking to external services. How do we stop the

362
00:17:26.799 --> 00:17:30.559
<v Speaker 1>code from turning into a giant, tangled mess. What are

363
00:17:30.559 --> 00:17:35.160
<v Speaker 1>the foundations for scalable design, modularity integrating services cleanly?

364
00:17:35.480 --> 00:17:38.920
<v Speaker 2>That's a critical concern as apps evolve. That program dot

365
00:17:38.960 --> 00:17:41.960
<v Speaker 2>cs file in the book's example, it apparently swelled from

366
00:17:41.960 --> 00:17:43.880
<v Speaker 2>one hundred and ninety one lines to four hundred and

367
00:17:43.880 --> 00:17:44.400
<v Speaker 2>seventy nine.

368
00:17:44.400 --> 00:17:46.440
<v Speaker 1>Wow. Yeah, that gets on wieldy fast.

369
00:17:46.279 --> 00:17:50.799
<v Speaker 2>So refactoring fromodularity becomes essential. One useful technique mentioned is

370
00:17:50.880 --> 00:17:53.599
<v Speaker 2>using a code map, a visualization tool to see the

371
00:17:53.640 --> 00:17:57.160
<v Speaker 2>relationships between different parts of your code. Helps you spot complexity.

372
00:17:57.240 --> 00:17:58.680
<v Speaker 1>A codemap interesting.

373
00:17:58.880 --> 00:18:03.000
<v Speaker 2>The goal is a logical project structure, maybe separate folders

374
00:18:03.039 --> 00:18:06.720
<v Speaker 2>for commands and services. This improves readability, makes it easier

375
00:18:06.759 --> 00:18:09.400
<v Speaker 2>to maintain, and crucially, it makes it easier to add

376
00:18:09.480 --> 00:18:13.279
<v Speaker 2>new features without breaking existing ones and easier for new

377
00:18:13.319 --> 00:18:14.480
<v Speaker 2>developers to onboard.

378
00:18:14.880 --> 00:18:18.200
<v Speaker 1>Makes sense and are there core software design principles that

379
00:18:18.279 --> 00:18:18.720
<v Speaker 1>guide this?

380
00:18:18.960 --> 00:18:23.200
<v Speaker 2>Absolutely? The dependency inversion principle or DIP is key here.

381
00:18:23.839 --> 00:18:29.119
<v Speaker 2>It's one of the solid principles fundamental ideas for building maintainable, scalable.

382
00:18:28.640 --> 00:18:32.519
<v Speaker 1>Software dependency inversions. Fancy, what's the core idea?

383
00:18:32.880 --> 00:18:35.160
<v Speaker 2>It basically says that high level parts of your system

384
00:18:35.160 --> 00:18:38.880
<v Speaker 2>shouldn't depend directly on low level concrete implementations. They should

385
00:18:38.880 --> 00:18:41.000
<v Speaker 2>depend on abstractions, usually interfaces.

386
00:18:41.200 --> 00:18:43.039
<v Speaker 1>Okay, can you give an analogy.

387
00:18:43.039 --> 00:18:46.079
<v Speaker 2>Maybe think of your car steering wheel. It's not welded

388
00:18:46.079 --> 00:18:48.240
<v Speaker 2>directly to the wheels, right now, that'd be weird. There's

389
00:18:48.240 --> 00:18:53.119
<v Speaker 2>an interface that the steering column, the linkage, a standardized connection.

390
00:18:53.440 --> 00:18:55.559
<v Speaker 2>If you want to swap your regular tires for I

391
00:18:55.559 --> 00:18:58.319
<v Speaker 2>don't know, monster truck tires, Okay, you change the tires,

392
00:18:58.599 --> 00:19:01.119
<v Speaker 2>but the steering wheel and how it can generally stays

393
00:19:01.160 --> 00:19:03.119
<v Speaker 2>the same. The interface decouples them.

394
00:19:03.319 --> 00:19:05.400
<v Speaker 1>Ah. I see, So the steering wheel depends on the

395
00:19:05.400 --> 00:19:09.640
<v Speaker 1>idea of steerable wheels, not one specific type of wheel exactly.

396
00:19:10.079 --> 00:19:12.559
<v Speaker 2>In code, this means your command logic depends on an

397
00:19:12.599 --> 00:19:16.720
<v Speaker 2>ibookmark service interface, not directly on the concrete bookmark service

398
00:19:16.759 --> 00:19:19.119
<v Speaker 2>class that might talk to a specific database and the

399
00:19:19.160 --> 00:19:23.279
<v Speaker 2>benefit decoupling. It makes the system way more flexible, easier

400
00:19:23.279 --> 00:19:26.559
<v Speaker 2>to maintain. If you change how bookmarks are stored, maybe

401
00:19:26.599 --> 00:19:29.720
<v Speaker 2>move from a file to a database, you only change

402
00:19:29.720 --> 00:19:33.960
<v Speaker 2>the concrete bookmark service implementation. The commands using the ibookmark

403
00:19:34.000 --> 00:19:36.720
<v Speaker 2>service interface don't need to change at all. It stops

404
00:19:36.799 --> 00:19:38.839
<v Speaker 2>changes rippling through your whole codebase.

405
00:19:39.160 --> 00:19:42.799
<v Speaker 1>That decoupling sounds incredibly valuable. So how does dot net

406
00:19:42.839 --> 00:19:45.920
<v Speaker 1>actually help us implement this? Put DIP into action.

407
00:19:46.359 --> 00:19:49.119
<v Speaker 2>Dot Net has excellent built in support for dependency injection

408
00:19:49.400 --> 00:19:52.680
<v Speaker 2>or DEI is the technique that makes DIP practical.

409
00:19:52.839 --> 00:19:54.079
<v Speaker 1>Okay, Dependency injection.

410
00:19:54.200 --> 00:19:57.440
<v Speaker 2>Instead of your command code manually creating a new bookmark service,

411
00:19:57.759 --> 00:20:00.079
<v Speaker 2>the DI container, managed by things like host builder or

412
00:20:00.079 --> 00:20:03.960
<v Speaker 2>anservice collection and modern dot Net automatically provides an instance

413
00:20:04.000 --> 00:20:07.200
<v Speaker 2>of the required service I bookmark service when the command

414
00:20:07.240 --> 00:20:07.640
<v Speaker 2>needs it.

415
00:20:07.759 --> 00:20:11.839
<v Speaker 1>So the framework handles creating and providing the dependencies.

416
00:20:11.200 --> 00:20:15.440
<v Speaker 2>Right it injects them. This makes future changes much easier

417
00:20:15.559 --> 00:20:18.279
<v Speaker 2>because you typically only need to register the service and

418
00:20:18.319 --> 00:20:22.359
<v Speaker 2>its implementation in one central place your startup configuration. You

419
00:20:22.400 --> 00:20:24.519
<v Speaker 2>don't have to hunt down every place the service is

420
00:20:24.599 --> 00:20:27.599
<v Speaker 2>used and update it much cleaner, much easier to manage

421
00:20:27.680 --> 00:20:28.640
<v Speaker 2>as the app grows.

422
00:20:28.920 --> 00:20:32.039
<v Speaker 1>That sounds much better. What about reaching outside our CLI

423
00:20:32.079 --> 00:20:34.519
<v Speaker 1>app using other systems or services.

424
00:20:34.680 --> 00:20:38.480
<v Speaker 2>Yeah, consuming external APIs and services super common and powerful.

425
00:20:38.599 --> 00:20:41.640
<v Speaker 2>Why reinvent the wheel right exactly? It lets you focus

426
00:20:41.680 --> 00:20:44.839
<v Speaker 2>on your core logic and delegate other things, maybe payments,

427
00:20:44.960 --> 00:20:48.240
<v Speaker 2>advanced logging, or like in the books, example, a separate

428
00:20:48.279 --> 00:20:53.440
<v Speaker 2>bookmark synchronization service to specialized external systems. It leverages expert solutions.

429
00:20:53.759 --> 00:20:56.880
<v Speaker 1>So how do we talk to those external services properly

430
00:20:56.920 --> 00:20:59.559
<v Speaker 1>and securely? In dot Net? We need good performance, good

431
00:20:59.599 --> 00:21:01.240
<v Speaker 1>resource management for talking.

432
00:21:01.119 --> 00:21:04.240
<v Speaker 2>To external APIs. Dot Net's HTTP client is the tool,

433
00:21:04.799 --> 00:21:07.599
<v Speaker 2>but crucially you should use IHTTP client.

434
00:21:07.279 --> 00:21:10.559
<v Speaker 1>Factory HTP client factory. Why that Specifically?

435
00:21:10.960 --> 00:21:14.680
<v Speaker 2>It manages the life cycle of HTTP client instances properly.

436
00:21:15.000 --> 00:21:18.400
<v Speaker 2>Helps avoid common problems like socket exhaustion, which can happen

437
00:21:18.440 --> 00:21:20.960
<v Speaker 2>if you create and dispose of too many HTP client

438
00:21:20.960 --> 00:21:25.400
<v Speaker 2>instances directly. It pools and reuses them efficiently. Better performance,

439
00:21:25.680 --> 00:21:27.279
<v Speaker 2>better resource management.

440
00:21:27.079 --> 00:21:29.880
<v Speaker 1>Okay, good practice. Any architectural patterns recommended here?

441
00:21:30.000 --> 00:21:33.160
<v Speaker 2>Yes, the service agent pattern is really insightful here. Think

442
00:21:33.160 --> 00:21:36.400
<v Speaker 2>of it like a dedicated diplomat or translator for your app.

443
00:21:36.640 --> 00:21:40.519
<v Speaker 2>When talking to a specific external service a service agent. Yeah,

444
00:21:40.720 --> 00:21:45.079
<v Speaker 2>instead of your main CLI command logic making raw HTDP calls,

445
00:21:45.079 --> 00:21:49.440
<v Speaker 2>figuring out URLs, header's authentication for some external API, which

446
00:21:49.480 --> 00:21:52.599
<v Speaker 2>can get messy, it just talks to this specific agent class,

447
00:21:52.759 --> 00:21:54.960
<v Speaker 2>like maybe a bookmark sinkur agent. It tells the agent, hey,

448
00:21:55.000 --> 00:21:57.920
<v Speaker 2>sink these bookmarks. The agent then handles all the nitty

449
00:21:57.920 --> 00:22:02.039
<v Speaker 2>gritty details of talking to the actual external bookmark sinker API,

450
00:22:02.480 --> 00:22:07.440
<v Speaker 2>formatting the request, handling API quarks, retries, authentication, parsing the

451
00:22:07.519 --> 00:22:08.400
<v Speaker 2>response AH.

452
00:22:08.440 --> 00:22:10.960
<v Speaker 1>So it encapsulates all the communication logic for that specific

453
00:22:11.039 --> 00:22:12.680
<v Speaker 1>external service exactly.

454
00:22:12.759 --> 00:22:17.279
<v Speaker 2>It dramatically simplifies your core command logic, centralizes the API

455
00:22:17.359 --> 00:22:21.000
<v Speaker 2>interaction details, and makes it much easier to change or

456
00:22:21.079 --> 00:22:24.319
<v Speaker 2>update how you talk to that external service later without

457
00:22:24.359 --> 00:22:26.079
<v Speaker 2>messing up your main application code.

458
00:22:26.480 --> 00:22:30.559
<v Speaker 1>Reduces that tight coupling That service agent pattern sounds really clean,

459
00:22:30.960 --> 00:22:33.519
<v Speaker 1>and it also leads us nicely into our next really

460
00:22:33.559 --> 00:22:37.799
<v Speaker 1>critical area, quality assurance and security. How do we make

461
00:22:37.839 --> 00:22:41.400
<v Speaker 1>sure this app we've built is reliable, trustworthy and safe

462
00:22:41.400 --> 00:22:42.079
<v Speaker 1>for users?

463
00:22:42.319 --> 00:22:45.799
<v Speaker 2>Absolutely crucial. Testing is your safety net? Simple as that

464
00:22:45.880 --> 00:22:49.119
<v Speaker 2>your safety net. It ensures new features work obviously, but

465
00:22:49.319 --> 00:22:53.920
<v Speaker 2>just as importantly it prevents regressions, you know, accidentally breaking

466
00:22:53.920 --> 00:22:55.440
<v Speaker 2>something that used to work when you add a new

467
00:22:55.440 --> 00:22:56.319
<v Speaker 2>feature or fix a bug.

468
00:22:56.440 --> 00:22:59.079
<v Speaker 1>Yeah, regressions are the worst. So how do we approach

469
00:22:59.119 --> 00:22:59.960
<v Speaker 1>testing systematic?

470
00:23:00.319 --> 00:23:02.799
<v Speaker 2>The pyramid of testing is a good mental model. It

471
00:23:02.839 --> 00:23:03.880
<v Speaker 2>outlines different levels.

472
00:23:03.960 --> 00:23:04.920
<v Speaker 1>Okay, what are the levels?

473
00:23:04.960 --> 00:23:07.799
<v Speaker 2>At the broad base, you have unit tests small fast

474
00:23:07.839 --> 00:23:11.759
<v Speaker 2>tests verifying individual methods or functions in isolation, often using mocking,

475
00:23:11.799 --> 00:23:15.240
<v Speaker 2>which we should talk about unit tests first. Then integration tests.

476
00:23:15.519 --> 00:23:19.119
<v Speaker 2>These check that different components work together correctly, like does

477
00:23:19.160 --> 00:23:21.359
<v Speaker 2>your service layer talk to the database properly?

478
00:23:21.440 --> 00:23:21.799
<v Speaker 1>Got it?

479
00:23:22.079 --> 00:23:26.200
<v Speaker 2>Above that? System tests These are end to end tests

480
00:23:26.440 --> 00:23:30.960
<v Speaker 2>verifying the entire applications functionality from the user's perspective, Does

481
00:23:31.079 --> 00:23:33.720
<v Speaker 2>the bookmark ad command actually add a bookmark?

482
00:23:33.839 --> 00:23:34.759
<v Speaker 1>A whole flow?

483
00:23:35.079 --> 00:23:38.160
<v Speaker 2>Right? And at the peak acceptance tests which confirm the

484
00:23:38.200 --> 00:23:41.440
<v Speaker 2>app meets the actual user requirements. You also have functional

485
00:23:41.480 --> 00:23:43.680
<v Speaker 2>tests what it does versus non functional tests? How well

486
00:23:43.680 --> 00:23:45.920
<v Speaker 2>it does it? Like performance or security testing.

487
00:23:46.160 --> 00:23:49.400
<v Speaker 1>That's a comprehensive pyramid for a practical approach, though, what

488
00:23:49.440 --> 00:23:52.759
<v Speaker 1>should we really focus on testing? And maybe what shouldn't

489
00:23:52.759 --> 00:23:53.839
<v Speaker 1>we waste time testing?

490
00:23:53.920 --> 00:23:57.880
<v Speaker 2>Good question? Focus on testing the happy path everything works

491
00:23:57.960 --> 00:24:03.480
<v Speaker 2>is expected, but also critically test the unhappy paths invalid

492
00:24:03.519 --> 00:24:06.160
<v Speaker 2>input errors, user hitting sutrol plus.

493
00:24:06.000 --> 00:24:08.960
<v Speaker 1>Two okay, both success and failure cases exactly.

494
00:24:09.279 --> 00:24:13.599
<v Speaker 2>Test method behavior, check fortoon values, ensure exceptions are thrown

495
00:24:13.640 --> 00:24:17.599
<v Speaker 2>and handled correctly. What not to test? Generally, don't test

496
00:24:17.640 --> 00:24:22.839
<v Speaker 2>external frameworks themselves or simple data transfer objects DTOs those

497
00:24:22.839 --> 00:24:26.720
<v Speaker 2>plain data structures. Their creators should have tested them. Focus

498
00:24:26.720 --> 00:24:28.279
<v Speaker 2>on your logic and when?

499
00:24:28.359 --> 00:24:31.720
<v Speaker 1>Do these different tests typically run in the development cycle.

500
00:24:32.039 --> 00:24:35.400
<v Speaker 2>Unit tests run them frequently, like before every code commit.

501
00:24:35.480 --> 00:24:38.960
<v Speaker 2>Ideally they should be fast. Integration tests usually run after

502
00:24:39.079 --> 00:24:42.799
<v Speaker 2>unit tests pass. Maybe in your CI pipeline. Smoke tests

503
00:24:42.839 --> 00:24:44.799
<v Speaker 2>are quick checks right after deployment to make sure the

504
00:24:44.839 --> 00:24:48.039
<v Speaker 2>basics are working. System tests often run in a staging

505
00:24:48.119 --> 00:24:50.000
<v Speaker 2>environment before the final production release.

506
00:24:50.240 --> 00:24:51.880
<v Speaker 1>How do you set up testing in dot net?

507
00:24:52.039 --> 00:24:54.720
<v Speaker 2>It's easy. Dot Net new ms test or x unit

508
00:24:54.839 --> 00:24:57.680
<v Speaker 2>end unit creates a test project. Then you structure your

509
00:24:57.720 --> 00:25:01.480
<v Speaker 2>test classes logically, maybe mirroring your application structure, like link

510
00:25:01.519 --> 00:25:03.559
<v Speaker 2>command tests for the Bookmark apps link command.

511
00:25:03.839 --> 00:25:06.799
<v Speaker 1>Okay, you mentioned mocking for unit tests. What's that about,

512
00:25:07.200 --> 00:25:10.359
<v Speaker 1>especially when dealing with external things like databases or web

513
00:25:10.359 --> 00:25:13.160
<v Speaker 1>services that can be slow or unreliable during tests.

514
00:25:13.519 --> 00:25:16.720
<v Speaker 2>Right, This is where mocking is essential for effective unit testing.

515
00:25:17.240 --> 00:25:19.359
<v Speaker 2>Think of it like using a stand in act or

516
00:25:19.440 --> 00:25:23.079
<v Speaker 2>during a play rehearsal the stand in Yeah, libraries like

517
00:25:23.240 --> 00:25:27.079
<v Speaker 2>n substitute or mock fake ad easy let you create

518
00:25:27.240 --> 00:25:31.480
<v Speaker 2>fake controlled versions of your dependencies, like a fig ibookmark

519
00:25:31.519 --> 00:25:34.119
<v Speaker 2>service that doesn't actually talk to a database, but just

520
00:25:34.200 --> 00:25:38.160
<v Speaker 2>returns pre defined data or verifies that certain methods were called.

521
00:25:38.279 --> 00:25:41.359
<v Speaker 1>Ah, So you can test your command logic without needing

522
00:25:41.440 --> 00:25:43.960
<v Speaker 1>a real database or web service running exactly.

523
00:25:44.440 --> 00:25:47.640
<v Speaker 2>It lets you test your method in complete isolation. It

524
00:25:47.680 --> 00:25:51.920
<v Speaker 2>eliminates failures caused by external factors slow network service being down.

525
00:25:52.480 --> 00:25:54.759
<v Speaker 2>If a unit test fails when using mocks, you know

526
00:25:54.799 --> 00:25:56.920
<v Speaker 2>the bug is almost certainly in your code, not the

527
00:25:57.000 --> 00:26:00.160
<v Speaker 2>dependency makes debugging way faster and moraliable.

528
00:26:00.240 --> 00:26:02.759
<v Speaker 1>That makes a lot of sense for isolating tests. Now,

529
00:26:02.839 --> 00:26:06.680
<v Speaker 1>shifting gears slightly but equally critical security. Is this something

530
00:26:06.720 --> 00:26:07.640
<v Speaker 1>we just tack on at the end?

531
00:26:07.720 --> 00:26:10.880
<v Speaker 2>Oh? Absolutely not. That's a recipe for disaster security is

532
00:26:10.920 --> 00:26:13.160
<v Speaker 2>an afterthought. It has to be woven through the entire

533
00:26:13.200 --> 00:26:14.400
<v Speaker 2>application life cycle.

534
00:26:14.480 --> 00:26:16.960
<v Speaker 1>The entire life cycle from the very beginning.

535
00:26:17.039 --> 00:26:22.680
<v Speaker 2>Ye yes. Starting with design, use threat modeling techniques like STRIDE.

536
00:26:22.599 --> 00:26:24.880
<v Speaker 1>Or dread Stride dread.

537
00:26:24.680 --> 00:26:28.119
<v Speaker 2>There are structured ways to brainstorm potential threats. STRIDE stands

538
00:26:28.160 --> 00:26:34.240
<v Speaker 2>for spoofing, tampering, repudiation, information disclosure, denial of service, elevation

539
00:26:34.319 --> 00:26:37.079
<v Speaker 2>of privilege. It helps you think like an attacker early on.

540
00:26:37.160 --> 00:26:39.680
<v Speaker 1>Okay, thinking like an attacker during design. What else?

541
00:26:39.960 --> 00:26:44.680
<v Speaker 2>Architecture using principles like defense and depth, securing communication channels, development,

542
00:26:44.720 --> 00:26:47.799
<v Speaker 2>following secure coding practices, being aware of things like the

543
00:26:47.799 --> 00:26:52.079
<v Speaker 2>OATS top ten common vulnerabilities, keeping your libraries and dependencies

544
00:26:52.160 --> 00:26:52.759
<v Speaker 2>up to date.

545
00:26:52.799 --> 00:26:55.279
<v Speaker 1>Right outdated libraries are a big risk, huge risk.

546
00:26:55.839 --> 00:27:01.680
<v Speaker 2>Then testing penetration, testing, vulnerability assessments, deploy security ICD pipelines,

547
00:27:01.839 --> 00:27:05.319
<v Speaker 2>managing secrets properly, no apikes, and source code definitely not

548
00:27:05.720 --> 00:27:10.119
<v Speaker 2>ongoing usage, monitoring for suspicious activity, patching vulnerabilities promptly, and

549
00:27:10.200 --> 00:27:13.079
<v Speaker 2>even logging being careful not the logs sensitive data or

550
00:27:13.160 --> 00:27:15.480
<v Speaker 2>using tools like sarah log to sanitize it if you must.

551
00:27:15.839 --> 00:27:17.200
<v Speaker 2>Security is everywhere.

552
00:27:17.400 --> 00:27:21.279
<v Speaker 1>Wow, Okay, it really is a continuous process. Are there

553
00:27:21.319 --> 00:27:26.160
<v Speaker 1>any specific tools, maybe simpler ones that developers can use

554
00:27:26.200 --> 00:27:28.920
<v Speaker 1>to check the security of their dot net apps without

555
00:27:28.960 --> 00:27:31.000
<v Speaker 1>being full blown security experts.

556
00:27:31.119 --> 00:27:34.640
<v Speaker 2>Yeah, definitely, there are comprehensive tools like sonar, cub snack,

557
00:27:35.119 --> 00:27:38.240
<v Speaker 2>mend bolt. But for a great starting point right within

558
00:27:38.279 --> 00:27:41.160
<v Speaker 2>the dot net ecosystem, check out dot net audit.

559
00:27:41.319 --> 00:27:43.400
<v Speaker 1>Dot net audit built in yep.

560
00:27:43.440 --> 00:27:46.359
<v Speaker 2>You can run dot netlist package vulnerable. It checks your

561
00:27:46.359 --> 00:27:50.559
<v Speaker 2>project's Newgit packages against the GitHub advisory database and tells

562
00:27:50.559 --> 00:27:53.319
<v Speaker 2>you if you're using any versions with known vulnerabilities.

563
00:27:53.400 --> 00:27:55.599
<v Speaker 1>Oh, that's super useful and easy it is.

564
00:27:56.079 --> 00:27:59.240
<v Speaker 2>And dot netlist package outdated is also helpful if flags

565
00:27:59.240 --> 00:28:02.599
<v Speaker 2>libraries that aren't necessarily vulnerable now but are old and

566
00:28:02.680 --> 00:28:05.519
<v Speaker 2>might not be getting security patches anymore, prompting you to upgrade.

567
00:28:05.640 --> 00:28:06.759
<v Speaker 2>Quick checks anyone can do.

568
00:28:06.920 --> 00:28:09.880
<v Speaker 1>Fantastic. Okay, let's circle back to that bookmark singer external

569
00:28:09.920 --> 00:28:13.799
<v Speaker 1>service example. How do we actually secure the communication between

570
00:28:13.839 --> 00:28:16.960
<v Speaker 1>our CLI app and that service, especially if something like

571
00:28:17.000 --> 00:28:18.960
<v Speaker 1>an apike or token is involved?

572
00:28:19.039 --> 00:28:22.599
<v Speaker 2>Good question. Typically you'd implement authentication using something like a

573
00:28:22.599 --> 00:28:24.920
<v Speaker 2>personal access token or pit a PET.

574
00:28:25.160 --> 00:28:26.559
<v Speaker 1>Okay, how does that work?

575
00:28:26.880 --> 00:28:30.079
<v Speaker 2>Your CLI app needs to send this PT to the

576
00:28:30.119 --> 00:28:33.599
<v Speaker 2>external service with each request. A common way is via

577
00:28:33.640 --> 00:28:36.160
<v Speaker 2>a custom HGTP header like xpat.

578
00:28:36.319 --> 00:28:41.880
<v Speaker 1>So the token goes in the header securely hopefully over HTTPS.

579
00:28:41.079 --> 00:28:44.640
<v Speaker 2>Absolutely acts is non negotiable. There The external service then

580
00:28:44.680 --> 00:28:48.039
<v Speaker 2>receives a request, extracts a paid and validates to checks

581
00:28:48.039 --> 00:28:50.519
<v Speaker 2>if it's known, if it's still valid, not expired, has

582
00:28:50.559 --> 00:28:52.000
<v Speaker 2>the right permissions.

583
00:28:51.519 --> 00:28:54.319
<v Speaker 1>And the CLI app needs to handle the responses like

584
00:28:54.359 --> 00:28:56.079
<v Speaker 1>if the token is invalid exactly.

585
00:28:56.079 --> 00:28:57.720
<v Speaker 2>The service might respond with a four to H one

586
00:28:57.759 --> 00:29:00.640
<v Speaker 2>and off rised or four H three forbidden. Your cli

587
00:29:00.759 --> 00:29:03.759
<v Speaker 2>needs to handle those responses gracefully, maybe prompt the user

588
00:29:03.799 --> 00:29:05.319
<v Speaker 2>to re enter their token or update it.

589
00:29:05.440 --> 00:29:07.960
<v Speaker 1>Where should the user store this pat? Not hard coded?

590
00:29:08.039 --> 00:29:10.200
<v Speaker 2>Right, definitely not hard coded. A common approach is to

591
00:29:10.240 --> 00:29:13.960
<v Speaker 2>store it in an environment variable like bookmark pat. The

592
00:29:14.000 --> 00:29:16.279
<v Speaker 2>cli app can then read it from the environment when needed.

593
00:29:16.680 --> 00:29:18.960
<v Speaker 2>Keeps the token out of source code and separate from

594
00:29:18.960 --> 00:29:21.039
<v Speaker 2>the application deployment much more secure.

595
00:29:21.160 --> 00:29:23.920
<v Speaker 1>Okay, environment variable for the pet. Got it? So I've

596
00:29:23.920 --> 00:29:28.279
<v Speaker 1>built it, made it robust, interactive, modular, secure, tested it. Wow.

597
00:29:28.640 --> 00:29:32.319
<v Speaker 1>Now the final hurdle. How do we actually get this

598
00:29:32.480 --> 00:29:35.359
<v Speaker 1>amazing CLI app into the hands of our users. Let's

599
00:29:35.400 --> 00:29:37.480
<v Speaker 1>talk packaging and deployment.

600
00:29:37.160 --> 00:29:40.000
<v Speaker 2>Right the final mile. First, let's just clarify the terms

601
00:29:40.039 --> 00:29:41.319
<v Speaker 2>because they sometimes get mixed up.

602
00:29:41.440 --> 00:29:41.759
<v Speaker 1>Okay.

603
00:29:41.920 --> 00:29:45.599
<v Speaker 2>Packaging is bundling everything needed to your app's code dependencies

604
00:29:45.599 --> 00:29:49.599
<v Speaker 2>into a deployable unit. Distribution is making that package available

605
00:29:49.640 --> 00:29:53.200
<v Speaker 2>like putting on our website or repository, and deployment is

606
00:29:53.240 --> 00:29:56.240
<v Speaker 2>the actual act of installing and configuring it on the

607
00:29:56.319 --> 00:29:57.160
<v Speaker 2>user's machine.

608
00:29:57.200 --> 00:30:01.599
<v Speaker 1>Package, distribute, deploy Got it? So for our cross platform

609
00:30:01.680 --> 00:30:03.920
<v Speaker 1>dot netcli app? What are the main options?

610
00:30:04.119 --> 00:30:06.640
<v Speaker 2>You've got several good ones, and the best choice often

611
00:30:06.640 --> 00:30:09.480
<v Speaker 2>depends on your target audience. Like well, first, you can

612
00:30:09.519 --> 00:30:11.160
<v Speaker 2>package it as a dot net tool, a.

613
00:30:11.119 --> 00:30:13.880
<v Speaker 1>Dot Net tool like dot net tool install exactly.

614
00:30:14.079 --> 00:30:16.799
<v Speaker 2>You package your app as a standard nugat package using

615
00:30:16.880 --> 00:30:19.839
<v Speaker 2>dot netpack, then publish it to NuGet dot org or

616
00:30:19.880 --> 00:30:23.039
<v Speaker 2>a private feed. This is ideal for other developers or

617
00:30:23.079 --> 00:30:26.119
<v Speaker 2>it pros who already have the dot Net SDK installed.

618
00:30:26.160 --> 00:30:29.759
<v Speaker 2>They just run dot net tool installed global your tool name.

619
00:30:30.119 --> 00:30:31.359
<v Speaker 2>Super easy for that audience.

620
00:30:31.519 --> 00:30:32.640
<v Speaker 1>Okay, cool for devs.

621
00:30:32.720 --> 00:30:35.960
<v Speaker 2>What else? Second option a dock or container. You write

622
00:30:35.960 --> 00:30:37.920
<v Speaker 2>a Docker file that describes how to build an image

623
00:30:37.920 --> 00:30:40.200
<v Speaker 2>containing your app and its runtime dependencies.

624
00:30:40.279 --> 00:30:42.160
<v Speaker 1>Ah containerization yep.

625
00:30:42.480 --> 00:30:45.160
<v Speaker 2>You build the image, Docker build, push it to Docker

626
00:30:45.200 --> 00:30:48.519
<v Speaker 2>hub or another registry. Users then just need Docker Desktop

627
00:30:48.599 --> 00:30:51.359
<v Speaker 2>or WSL installed and they can Docker pull your image

628
00:30:51.359 --> 00:30:55.400
<v Speaker 2>and Docker run it. Great for portability, consistency across environments,

629
00:30:55.599 --> 00:30:56.920
<v Speaker 2>and often a reduced footprint.

630
00:30:57.279 --> 00:31:01.359
<v Speaker 1>Nice. Any options more geared towards say typical Windows users.

631
00:31:01.440 --> 00:31:04.680
<v Speaker 2>Yes, Third option a wingt package. Wing it is the

632
00:31:04.839 --> 00:31:05.960
<v Speaker 2>Windows package managed.

633
00:31:05.960 --> 00:31:07.480
<v Speaker 1>Oh yeah, wing it install right.

634
00:31:07.680 --> 00:31:11.279
<v Speaker 2>You create a manifest file basically metadata describing your app

635
00:31:11.839 --> 00:31:14.839
<v Speaker 2>using the wind create cli tool. You typically use dot

636
00:31:14.880 --> 00:31:17.920
<v Speaker 2>net published first to create a self contained executable that

637
00:31:17.960 --> 00:31:20.279
<v Speaker 2>includes the dot Net run time so the user doesn't

638
00:31:20.279 --> 00:31:23.759
<v Speaker 2>need dot Net installed separately. Then you submit your manifest

639
00:31:23.799 --> 00:31:27.000
<v Speaker 2>to the official wing itt repository. Windows users can then

640
00:31:27.039 --> 00:31:29.839
<v Speaker 2>just wing it install your app aid very seamless for them.

641
00:31:30.160 --> 00:31:34.359
<v Speaker 1>Three solid options dot Net tool, Docker wing it. Once

642
00:31:34.359 --> 00:31:37.119
<v Speaker 1>it's out there, though, how do we manage updates? Users

643
00:31:37.119 --> 00:31:39.160
<v Speaker 1>need a way to get new versions fixed bugs?

644
00:31:39.279 --> 00:31:42.960
<v Speaker 2>Versioning is crucial. The standard way is semantic versioning.

645
00:31:42.799 --> 00:31:45.400
<v Speaker 1>Or sever major dot minor dot exactly.

646
00:31:45.119 --> 00:31:48.039
<v Speaker 2>Major version bumps for breaking changes, minor for new features,

647
00:31:48.039 --> 00:31:51.880
<v Speaker 2>backward compatible, and patch for bug fixes. It clearly communicates

648
00:31:51.920 --> 00:31:53.759
<v Speaker 2>the nature of changes to users.

649
00:31:53.839 --> 00:31:56.319
<v Speaker 1>How does that work with the different packaging methods for

650
00:31:56.400 --> 00:31:57.160
<v Speaker 1>dot net tools.

651
00:31:57.200 --> 00:31:59.680
<v Speaker 2>You update the version number in your projects dot cs

652
00:31:59.720 --> 00:32:03.240
<v Speaker 2>pro file, run dot netpack and push the new nugat

653
00:32:03.279 --> 00:32:06.359
<v Speaker 2>package version. Users can update with dot a tool update

654
00:32:06.359 --> 00:32:10.680
<v Speaker 2>global or install specific versions for docer. You use tags

655
00:32:10.720 --> 00:32:14.920
<v Speaker 2>when building your image doctor build, DASTMIAPP, dot one, dot one,

656
00:32:14.960 --> 00:32:18.400
<v Speaker 2>bond zero. Users pull the specific tag they need. For

657
00:32:18.480 --> 00:32:20.720
<v Speaker 2>wing it, you update the version in your manifest file

658
00:32:20.799 --> 00:32:23.519
<v Speaker 2>and resubmit it. Wing It handles the upgrade process for

659
00:32:23.640 --> 00:32:24.920
<v Speaker 2>users via wing it upgrade.

660
00:32:25.039 --> 00:32:27.839
<v Speaker 1>Okay, version and handled. What about performance? We want our

661
00:32:27.839 --> 00:32:31.279
<v Speaker 1>Coli app to be fast, especially in production. Do these

662
00:32:31.279 --> 00:32:34.039
<v Speaker 1>packaging choices matter? And how do we optimize?

663
00:32:34.079 --> 00:32:34.519
<v Speaker 2>Performance?

664
00:32:34.599 --> 00:32:34.640
<v Speaker 1>Is?

665
00:32:34.680 --> 00:32:38.480
<v Speaker 2>Definitely key and yes, packaging choices can influence it. First rule,

666
00:32:38.799 --> 00:32:41.960
<v Speaker 2>always compile and release mode for production build plug debug mode,

667
00:32:42.039 --> 00:32:45.400
<v Speaker 2>never debug mode for production. Release mode enables significant compiler

668
00:32:45.440 --> 00:32:47.920
<v Speaker 2>optimizations that make your code run much faster and often

669
00:32:48.039 --> 00:32:48.799
<v Speaker 2>use less memory.

670
00:32:48.880 --> 00:32:50.319
<v Speaker 1>Okay, release mode? What else?

671
00:32:50.519 --> 00:32:54.720
<v Speaker 2>For maximum efficiency, specially startup time, consider platform specific compilation.

672
00:32:55.319 --> 00:32:57.920
<v Speaker 2>This tailor's the output binary for a specific OS and

673
00:32:58.000 --> 00:33:00.799
<v Speaker 2>CPU architecture, or even go step further with ahead of

674
00:33:00.839 --> 00:33:05.160
<v Speaker 2>time AOT compilation. AOT What's that it precompiles your dot

675
00:33:05.160 --> 00:33:08.200
<v Speaker 2>net code directly to nat a machine code before deployment

676
00:33:08.559 --> 00:33:11.880
<v Speaker 2>instead of relying on the just in time JIT compiler

677
00:33:11.920 --> 00:33:15.400
<v Speaker 2>at run time. This can dramatically improve startup performance and

678
00:33:15.440 --> 00:33:19.039
<v Speaker 2>reduce the app size and dependencies. Makes it feel incredibly snappy.

679
00:33:19.240 --> 00:33:22.200
<v Speaker 1>Nice. The book had some examples too, right, like optimizing

680
00:33:22.279 --> 00:33:23.359
<v Speaker 1>JSON serialization.

681
00:33:23.559 --> 00:33:27.480
<v Speaker 2>Yeah, optimizing things like Jason serializer serialized ACNC by using

682
00:33:27.559 --> 00:33:32.960
<v Speaker 2>filestream directly can improve ioperformance significantly compared to say, writing

683
00:33:32.960 --> 00:33:35.359
<v Speaker 2>to a memory stream. First, little things add up.

684
00:33:35.640 --> 00:33:39.119
<v Speaker 1>How do we find these performance bottlenecks in the first place?

685
00:33:39.400 --> 00:33:43.000
<v Speaker 2>Profiling is key. Tools like benchmark dot net are fantastic

686
00:33:43.039 --> 00:33:45.640
<v Speaker 2>for micro benchmarking specific pieces of code. It gives you

687
00:33:45.680 --> 00:33:49.839
<v Speaker 2>precise metrics mean execution time, error margin, standard deviation for

688
00:33:49.880 --> 00:33:54.880
<v Speaker 2>consistency allocated memory very detailed, helps you identify hotspots, methods

689
00:33:54.880 --> 00:33:57.759
<v Speaker 2>that are called very frequently, hot spots, and hot paths

690
00:33:58.160 --> 00:34:01.960
<v Speaker 2>the code execution paths taken most often target your optimization

691
00:34:01.960 --> 00:34:05.559
<v Speaker 2>efforts there for the biggest impact. And for monitoring and production,

692
00:34:05.839 --> 00:34:09.119
<v Speaker 2>tools like Azure Application Insights can give you real time

693
00:34:09.159 --> 00:34:12.320
<v Speaker 2>performance data and help you spot issues as they happen.

694
00:34:12.480 --> 00:34:18.239
<v Speaker 1>Okay, profiling and monitoring essential. So wrapping this all up.

695
00:34:18.320 --> 00:34:21.159
<v Speaker 1>What does this journey mean for you, our listener.

696
00:34:21.639 --> 00:34:24.519
<v Speaker 2>Well, we've gone from understanding what CLI apps even.

697
00:34:24.320 --> 00:34:26.760
<v Speaker 1>Are, right, they're surprising ubiquity.

698
00:34:26.320 --> 00:34:29.119
<v Speaker 2>Through building them with powerful dot Net tools like system

699
00:34:29.159 --> 00:34:32.039
<v Speaker 2>dot command line, making them interactive and user friendly with

700
00:34:32.079 --> 00:34:32.840
<v Speaker 2>Spectro dot.

701
00:34:32.679 --> 00:34:36.679
<v Speaker 1>Console, making them robust with validation, air handling logging.

702
00:34:36.519 --> 00:34:42.119
<v Speaker 2>Designing them well using modularity, DIPDI, integrating external services.

703
00:34:41.760 --> 00:34:44.400
<v Speaker 1>Safely, securing them, testing them thoroughly.

704
00:34:44.239 --> 00:34:48.000
<v Speaker 2>Optimizing for performance, and finally packaging and deploying them using

705
00:34:48.039 --> 00:34:51.119
<v Speaker 2>various methods like dot net tools, Docker or wing it.

706
00:34:51.119 --> 00:34:53.280
<v Speaker 1>It's quite a journey, it really is, and it shows

707
00:34:53.280 --> 00:34:56.599
<v Speaker 1>that these CLI applications, even without a fancy graphical interface,

708
00:34:56.639 --> 00:34:59.920
<v Speaker 1>are incredibly powerful tools for automation for products.

709
00:35:00.719 --> 00:35:06.079
<v Speaker 2>Absolutely, they streamline workflows, solve real problems efficiently. Don't underestimate

710
00:35:06.119 --> 00:35:07.639
<v Speaker 2>the power of the command line.

711
00:35:08.000 --> 00:35:10.519
<v Speaker 1>So here's a final thought, maybe a provocative one for

712
00:35:10.599 --> 00:35:14.760
<v Speaker 1>you to chew on. Think about that bookmark application or

713
00:35:14.880 --> 00:35:17.960
<v Speaker 1>just your own daily computer. Use those simple tasks you

714
00:35:18.000 --> 00:35:20.519
<v Speaker 1>do over and over with a mouse clicking through menus?

715
00:35:21.119 --> 00:35:24.360
<v Speaker 1>What if you could automate them? What comment maybe even

716
00:35:24.400 --> 00:35:28.639
<v Speaker 1>slightly annoying repetitive tasks in your workflow, personal or professional

717
00:35:29.039 --> 00:35:31.719
<v Speaker 1>could be dramatically sped up if you built a small,

718
00:35:31.840 --> 00:35:33.400
<v Speaker 1>simple CLI tool for them.

719
00:35:33.559 --> 00:35:36.519
<v Speaker 2>Yeah, think about the hidden value there. Saving clicks, sure,

720
00:35:36.719 --> 00:35:40.559
<v Speaker 2>but also saving context switches, reducing cognitive load. A simple

721
00:35:40.599 --> 00:35:42.679
<v Speaker 2>command could bring surprising benefits to.

722
00:35:42.639 --> 00:35:45.280
<v Speaker 1>Your day to day exactly. So we really encourage you

723
00:35:45.320 --> 00:35:48.400
<v Speaker 1>to explore the resources we've mentioned, especially to Johnny Bilminser's

724
00:35:48.400 --> 00:35:51.320
<v Speaker 1>book building CLI applications with c sharp and dot net,

725
00:35:51.519 --> 00:35:54.159
<v Speaker 1>and maybe check out libraries like system dot command line

726
00:35:54.159 --> 00:35:55.239
<v Speaker 1>and Spectro dot console.

727
00:35:55.320 --> 00:35:57.159
<v Speaker 2>Because you know, at the end of the day, as

728
00:35:57.239 --> 00:36:00.599
<v Speaker 2>the book wisely points out, your users aren't really interested

729
00:36:00.639 --> 00:36:04.880
<v Speaker 2>in your amazing coding skills or how elegantyourprogram dot cs.

730
00:36:04.639 --> 00:36:06.360
<v Speaker 1>Is huhuh, probably not.

731
00:36:06.639 --> 00:36:09.639
<v Speaker 2>What they're interested in is the value your application, your

732
00:36:09.639 --> 00:36:13.519
<v Speaker 2>CLI application brings to them. Does it solve their problem?

733
00:36:13.599 --> 00:36:15.000
<v Speaker 2>Does it make their life easier?

734
00:36:15.079 --> 00:36:17.840
<v Speaker 1>That's the bottom line. So if this deep dive has

735
00:36:17.920 --> 00:36:22.360
<v Speaker 1>sparked an idea, however small, grab those resources, start experimenting.

736
00:36:22.559 --> 00:36:24.840
<v Speaker 1>You might surprise yourself with the power you can unlock

737
00:36:24.880 --> 00:36:26.480
<v Speaker 1>with CLI tools in your own world.

738
00:36:26.679 --> 00:36:28.320
<v Speaker 2>It's all about the value you create.

739
00:36:28.519 --> 00:36:29.440
<v Speaker 1>Couldn't agree more
