How'd you like to listen to dot NetRocks with no ads? Easy? Become
a patron for just five dollars a month. You get access to a private
RSS feed where all the shows have no ads. Twenty dollars a month.
We'll get you that and a special dot NetRocks patron mug. Sign up now
at Patreon dot dot NetRocks dot com. Hey guess what it's dot NetRocks.
It's twenty twenty four. I'm Carl Franklin. That's Richie Campbell. Hey,
I am so all day? Yeah every time. How you doing, buddy?
I follow me everywhere. Sometimes I forget my name and I check it.
Sometimes I think I'm Joe Boxer, but I'm not. Due's Joe Boxer.
Is that a Canadian thing? Is the name on my underwear? Oh?
All right, it's like, what is that Canadian fruit of the loom?
Yeah, I don't think I would be named fruit, but Joe Joe
works. I'm the grapes you go, just fermented nicely. So how was
your you know, New Year's and Christmas and all that, well, and
everything's changed now we sold the big house in the city. You know,
I'm still working on the whole how do you sell this smart home thing?
But you know, now we don't have the big house in the center of
the family anymore, right, so things move around. So the younger daughter
hosted the Christmas meal, which was fun. Oh that's cool. That's got
to be great for her. Huh yeah. Yeah, But it just brings
back the memory for me when we got that house in two thousand of my
father looking through it at first Christmas going okay, you're it. That's right.
Yeah, I'm not doing it anymore. I't and I ever felt that
way per se, but suddenly we're in this position. Yeah. But you
know, the other thing is there is a guesthouse up here. So the
older daughter and her business partner or they're working from here for the next two
weeks. So they came up right after New Year's and just so we have
dinner most nights and that kind of thing. So it's like we're living in
a little village right now. Yeah, we're gonna have a quiz on Richard's
life a personal life after the show, So get out your pen you're all
paying attention in pencil. But if you're yeah, that's very very cool.
Just be aware when I'm recording. Here, I'm looking out at the ocean
as well, like that's the life. Yeah, I'm in the coolest studio
I've ever owned, so yeah, no, it's it looks great. And
Jimmy Bogart is here. We're going to talk to him in just a few
minutes. But first, Better Know a Framework? Awesome, a hard man,
what do you got? All right? So it's been a while since
I explained better No a Framework. It started out as just a piece in
the beginning of the show where I find a little piece of the dot neet
framework, maybe a name space or a class or something you didn't know was
there, and talk about it. And that quickly got old, and then
it became I it was several years of talking about the framework. Well yeah,
but this is the problem when you do a show for twenty years is
eventually you get through the framework, you get through the framework right, and
you run out of things, and then you know, it becomes more interesting
to find things that are going on in the world and just spotlight them.
So that's that's what it is. And today's spotlight is speaking of dot net
eight migrations. This is a class that I'm going to be teaching online in
January here January twenty seventh called Essential Blazer in dot net eight. So it's
a one day hands on remote class with Zoom and I've got a link to
it there on the website. And also, because this is episode eighteen eighty,
if you go to eighteen eighty dot pop, dot me or Blazer dot
appnix dot com, you'll get to it. Awesome, it's an event bright
page and I'm really really looking forward to it. See. This is the
cool thing is that this is what I do. I say, hey,
I'm teaching this class and that forces me to go through all my materials and
update it. And oh no, you announced the class before you finished writing
it. Goodness knows, well, I have the I have the content,
but it needs to be updated, it needs to be migrated, and then
you know, re explained within the context of eight. I got asked for
new geek outs for twenty twenty four, so I say, I sat down
and wrote two great abstracts. I can't wait to see what the talks are
like. Yeah, that's kind of a reality in our world. Is that's
it? You know what I really like? How about this? And I
said, out this abstract, you're like, yeah, do that. I'm
like, no, damn. But that now it's the fun part. You've
given yourself a deadline and you know you can do it. It's not that
you can't, so I mean, and let's be clear, it's how to
become a space fearing civilization and understanding nuclear power, two things I can probably
cough for an hour. I think I'll actually, you know, finish the
research right right, and okay, So that's what I got. Who's talking
to us today? Richard ah Grab a comment off of show eighteen sixty two,
the one we did back in September one. Jimmy Bogard maybe've heard of
him, never heard of when we were talking about his open source project or
one of the ones that he's involved with, Mediator, and Jimmy Scott said,
this is about right after the show publishing, he sent this message.
He said, we use Mediator for persistence of our settings in a solution,
and it's a dream when it compared to the service locator pattern, which sucked.
I understand sub drawbacks of Mediator, lots of tiny classes in direction,
but the key advantages far outweigh those. The centralization of data persistence logic,
which can be invoked from other than web APIs easily testable logic, and mediators
delegating handler pattern easily decorate requests with common handling logic. Yeah, oh,
Jimmy, I think you got a fan there. I guess so, making
one of the many. Yeah, without a doubt. I mean, we'll
pass out a lot to Jimmy. Look to Jimmy's and thanks so much for
your commented. A copy of music Koba is on its way to you.
And if you'd like a copy of music, go buy. I rite a
comment on the website at dot NetRocks dot com or on the facebooks. We
publish every show there, and if you comment there and everything on the show,
we'll send you a copy of music. Go by. And you can
follow us on Twitter if you want to. But the cool kids are hanging
out on Mastodon these days. I'm at Carl Franklin at tech hub dot social,
and I'm Rich Campbell at mastadon dot social. Send us a tuote,
a tweet, an ex, a poot, whatever the heck you call um,
just get it to us any of those things. I got an account
on threads now and blue Sky and they're all kind of fun. They are
kind of fun. Yeah, you know they each I like the smaller communities.
That reminds you of why we liked social media in the first place.
That's what I love about being on masted On is that there's just not there's
no advertising, there's no crap. It's just good stuff. All right.
Let's bring Jimmy Boguard on. Of course he's been on many times before.
He's the creator and maintainer of the popular OSS libraries, Auto Mapper and Mediator.
Jimmy's an independent software consultant based in Austin, Texas, and he has
received the MVP Award every year since two thousand and nine. Welcome back,
Jimmy. Good to see again. Yeah, I need to punch your frequent
flyer card there. I think it's number six including an open source panel,
So yeah, she is. I think I think you are more than the
number of episodes you've done. It's just a number of times you're referred to
YEA as the kind of the right way to do open source, like when
a nice person does the right thing by a project that sort of gets out
of control. I think of Jimmy Bogart just like the madness that you ended
up with automapper. Oh you didn't have to like bleep out something after they
mentioned my name. I also think, Jimmy, that you're a real generalist,
and you know, your knowledge and experience is vast horizontally as well as
vertically. I remember being in Nonslow maybe some with you overseas, and it
was before the conference started, and we were just sitting down maybe at breakfast
or something, and just riffed on messaging, you know, enterprise messaging.
And do you remember that conversation? No, I have a lot of but
you know, you can remember having conversations like that, I'm sure because it
was just great. It's really cool to have conversations with somebody who has this
knowledge that he doesn't get to share with most people. But you know,
these two people meet that you know, Oh yeah, enterprise messaging. Let's
talk about that for an hour. It's great. Okay, Now I am
remembering this conversation now, because again I don't it doesn't seem like people do
that very much in maybe the Dinaut space, I'm not sure, but it's
one of those things like once you get introduced to you like, oh,
there's this whole like universe of this technology that is really cool, but just
not a lot of people get to touch it very much. Yeah, true,
app it. That's also a space where it's a way of thinking when
you're building software at a certain scale or a certain level of complexity. And
if you're in that space, like, it's really awesome, and if you're
not, it's just people are looking at you like why would you do that?
That seems unnecessary? Like, well, look, come on, guys,
let's talk about fishing or seinfeld or something normal. I don't know they
I mean, you guys love talking about messaging. I don't mind talking about
messaging either. But the one that I have to stop myself on home assistant,
Like, if you're into home Assistant, we could talk for days.
If you are not, don't do it. Just not Ye. Anyway,
we were gonna talk about work because you've been up to stuff. Yeah,
yeah, I think this topic is like that was my life for about twelve
months, twelve to eighteen months. I'm doing this modernization migration effort. So
before the shipping of dot net, you were moving an app to to eight
or just to the modern version of dot net. So this is actually to
dot net six. And then eventually it did migrate to dot et eight.
But the big jump was to dot net six initially from dot net four eight,
Right, so what's the big hurdle getting rid of ASP dot net web
forms? Oh god, okay, so yeah that was I mean, the
first big thing we had to worry about was just what exists in their current
system and then what is the migration path to something over on dot net six?
And web forms is one of those things like there is no straightforward path.
It is a just a straight up re write. So there may be
like conversion tools to Blazer or something like that, but the web forms as
a model does not exist in dot net core or whatever you want to call
it. Dot Net six seven eight just doesn't exist. So do you just
rewrite those pages in your favorite flavor? Go Razor pages or Blazer or whatever
makes you happy. Pretty much, we've got some folks want to go,
like, you know, modern I is the page to begin with, So
you know, let's let's rewrite those set of pages to be like, you
know, spa angular sort of style, because maybe that component style architecture makes
a lot of sense for those pages, right, maybe it doesn't, so
really like a page by page whatever, this system that luckily only had one
web forms page, so it's just like a yeah, only one of those,
otherwise it would have been a big, you know, rewrite. But
we had to look through everything like what all the screens, you know,
what, all the technology the screens are built on, and then also all
the behind the scenes junk like the middleware, the any kind of back end
whatever junk that was going on as well. Now, did you have any
maintainers of the four point eight version, like was it compilable or was it
a you know, maintaining state at least? Oh? Yeah, so this
was like a live app that was still having ongoing feature development too. So
we as part of the migration process, we do we do worry about well,
we we can't ask the business to stop feature development for months at a
time. Why we'll do this migration process like that. That conversation never goes
well, yeah, right, we stop doing things you care about for things
that we need and you no doubt, when you're doing this migration you you
uncover some technical debt that you may or may not have known was there,
right, and invariably happens. Oh absolutely, So that was a big thing
for us to just we're gonna We're gonna turn over some rocks and see it
see something we don't want to, we don't expect, and like do we
just you know, turn the rock over again and be like w ooops,
let's just uh we try to or do we do we try to like fix
it? You know, why does this class exist? And why do we
keep passing it around? What is that? Yeah? There was Gordon Ramsey
going into your walk in you know you're like, what is that? Yeah?
I mean you we have cases where so one big thing we did at
the beginning was just analyze dependencies, like what does this application depend on?
And do those things exist and are supported in dot net core? And for
several of those things they didn't, So we said, do you know,
do we uh, you know, there's there's kind of like shims and bridges
that exist a don net core to to like call APIs and donit framework and
like cross your fingers hope they exist. But that's just a I didn't like
that because you only know if it's going to work at run time, and
we didn't want to know if we failed or not to like, oh we
tried to call this method, it doesn't actually exist. So we're just going
to blow up and a user see that. So as much as possible,
we said, well, let's go ahead and upgrade those things in place in
the donet framework gap and then we've got a straightforward migration path over to the
dot net core for those things. Did you use any like migration advisor tools
anything like that. There are a couple of those out there. There's one
that Microsoft had out there to uh, to analyze your dependencies and kind of
tell you, but it spit out a list of items. I was like
a spreadsheet with ten thousand rows to try to shift through this. If I
to take that much time, I'm going to do it myself. Yeah,
that's basically went through. It's like, well, we know what we what
we're looking for here, so we'll just go through and find those things.
So one good example is like e F six. This app used e F
six. E F six wasn't supported in don net core for a very long
time, and then eventually Microsoft said, this is a big hurdle for people
migrating, so we're going to release another version whose sole purpose is to you
know, cover the ninety nine percent of the features and support it on net
core. So that it's easier to upgrade. So that was one like okay,
we just we go from six six one to six' five. Okay,
now we get an opragrade path and we're not going to replace with ef
core because that is a big undertaking. Right, So that there is a
friendly version of ef now in six' five that makes that problem go away,
so you don't have to tear everything apart. Yeah, and so just
we we know we want upgrade eve core, but it lets us not have
to do everything all at once. That's where we're trying to make very small
incremental changes and we can still release to production every time to make this change.
Well, and the implication here is like, don't do the bridging back
to four eight. That's bad, but do take advantage of the Entity Framework
interim state because that's good. That's that'll be all right. It's a it's
a it's a shorter migration path because really we want to get a dot net
core that was the big thing dot net six seven eight, and then once
we were there, we could say, okay, let's go ahead and modernize
these other pieces that have better things or better ways of doing things in the
dot net seven eight space, right, and I mean, and then I
guess I begs that our early question, which is why are we doing this?
What are we getting for it? What is wrong with four eight?
Right? For this client though, they're they're big thing was like they wanted
to take advantage of things in a sp net core as the framework, right,
and so this application being built on that and being built on a st
four for eight, they saw that, well, that's really not getting up
dated or improved, and so this application is going to live on in the
future, then we want to be on top of a framework. So it's
less about dot at eight and more about asp net core, as this is
a web application that needs to live for another ten years and grow and improve
and change. Right, The question is would have been better to wait longer?
Like you were obviously not jumping on the earliest versions of VSP dot net
core, which were rough, but you've got a mature versions, Like when's
the right time to jump those new features? Yeah? So for this application
of particular, and the most of them, I see, dot net six
and seven was the right time for them, right, And the reason why
is that Microsoft introduced a few set of libraries and tools to make that migration
incrementally eight thousand times easier. Before that, if you wanted to migrate incrementally,
it was a very manual process to do so. And I can kind
of walk through what we used to do, what we used to do for
the dot net Core three one, for example, we we didn't want to
have a big bang migration, never want to do that. That's just fraught
with risk. The flip and the switch is just you know, how do
you how do you uh do regression testing of a whole system? Every that's
just like sucks more than flipping that switch, is flipping it back. Well,
we we we did do that. We yeah, So we wanted to
say there's no there's no roll back, there's only a roll forward. You
fix things and incimently go. So in the old days when we did this
and dont Core three, one way we would do this is we'd have two
apps. One is your dot net core app, one is a dot net
framework app, right, and then we would manually migrate pages from dot net
framework over to dot net Core. But from the kind of end user perspective,
they'd still be hitting don net framework even if this pages still the new
pages exist in don a Core. So we would introduce a reverse proxy in
front of both of those apps Engine X or something like that, where we'd
say, oh, this sprints, We've migrated these pages and so these pages,
so now go over to the new system that do not dyn ae core
app and the old pages go over there. So it was a very much
a you know, very manual process to be able to do all these sort
of things. But starting with done at six, Microsoft introduced a set of
tools to make that automatic switching between applications seamless and transparent and so much easier.
Yeah, now do you share the state with those two? Oh things?
Just that must be a bear. Okay, well let me explain first
the way that that's automatic switching works. It's it's wild. So I have
you all had folks talk about YARP before, yet another reverse products So yeah,
I think maybe Mark Rendel talked about it a little bit, but I
don't remember. Yeah, that makes sense because he has a tool as well
to make this migration easer. So YARP is yet another reverse proxy, and
it's a reverse proxy that can be hosted in the asp net core pipeline.
So it's kind of cool. So you can actually self host a reverse proxy
and that's exactly what this tooling does. It's the the name is kind of
strange, but its system Web adapters is the name of it. But the
idea is that you have a new asp net core application and that hosts a
reverse proxy and request will come in initially to your dot asp net core application,
and if that application cannot handle that request successfully, like the controller doesn't
exist, it will automatically forward that request over to your asp net full framework
application. So if I migrate a controller from four eight to asp net Core,
well suddenly that application can handle that request and is going to serve it
up. But if the can't, the controller is missing, just seamlessly forwards
that request and serves the response out over to Yeah, so it still serves
a response through the aspnt core application, but it's just proxy. We're doing
reverse proxy to your full framework application. So I guess what I'm getting at
is there's no real shared state except for you know, data persistence or whatever
that exists between those two things. Is there because they're completely different. Well,
okay, so there's going there has to be some shared states, so
things like authentication. Yeah, both applications have to know that you're logged in
right, So really, depending on your authentication scheme, you have to decide
how are you going to share that state. So if you're in an external
sso then you just configure those applications to be able to read that token effectively.
That's not a big game. Yeah, they both have rights to that
token. We weren't doing SS. We were doing cookie off that was self
hosted A yeah, yeah, yeah, so you've ever had to do effective
well how do I do do you do SSO with cookies? Do you have
both applications to be able to read the data protection certificate and be able to
be able to read that cookie? So that that is actually the way we
went was like, well, we have access to that data protection certificate,
so what we'll do is have they're I mean they're both initially hosted on the
same machine, Like they're just two I S Web applications self hosted, so
they both had access to the certificates. So we said, okay, the
dot net framework application is going to continue to do the log in and log
out and set the cookie, and then the dot net core application is then
able to read that cookie and be able to set the principal roles all that
sort of junk, and so that just worked fine that it could read the
information and effectively you're you're putting a flag in the ground that says, here's
our cut across is when we're going to change the dot net framework app to
give up authentication. But for now, yeah, that was actually the last
thing we change, was like, the very last thing we migrated was loging.
Okay, now now we have to worry about how do we share you
know, all that sort of stuff next with session session states, so we
we I mean, that's another shared state that the dot net core application has
to read and write session. The donet framework application has to read and write
session. So how do you share those two? How do you share that
sort of shared state? Now, unfortunately, this sequel schema of session is
not the same on both sides, So it's not like you can say,
well, I'm already doing a web farm scenario on donint framework that uses seql
as of backing storage. Those schemas are completely different, so they can't read
and write the same like sort of back end database of session states. Of
course, so what the system web adapters does is for any kind of sort
of shared state that you have between those two and session is just one example
of that is the system web adapters will expose an API indpoint in the Dinet
framework application via middleware like o in or whatever, and then when the Donet
core application needs to, like, oh, I need to read sessions state
instead of reading its own thing, it will make a API call to get
that stuff from the Dinat framework application. And then you just have these like
interface adapters that you're talking to to get that data out. But all like
the that makes sense, all the API stuff, like if there's an API
token, apikey thing to secure it, it's not exposed to the outside world
all that sort of junk, but it's now just exposing quote just exposing APIs
to be able to get that sort of data back out. Again. What's
kind of funny and ironic about this scenario is that all the things that Microsoft
has done in aspn AT to make it easier for development now becomes like a
problem when you're trying to have two of these things exists at the same time
sharing state, right, I mean like session state, the session bag,
you know, the application bag. All that stuff makes it easy for developers.
It's like boom on one system. But now that that simplicity that was
you know, making it easy is now hard. Yeah exactly. But luckily,
like they they recognize that and they've offered up solutions to be able to
do so. But not everything had a solution available for us. So a
good example is like shared code, like how do you share code between these
two applications and so for that stuff? Yeah exactly, So we pull things
up into a shared library that is now you know, dot net standard probably
so that both can can be able to use it. And so for business
logic that's pretty straightforward to do. For U I logic, there is no
sharing. Like we had a lot of copy paste, like any kind of
razor helper, things like those APIs are just different. We had a lot
of controller library like based controller classes. Those are just different name spaces.
We can't share those, so we just copy paste whatever. Are these that
much different for people actually using them? If the names are different, who
cares? But is it hard to keep both in your head? No?
No, Luckily, Like from the application developer perspective, it's really just changing
name spaces. Like there's slight you know, there's ie action results versus action
results. That's very little. But from like you could blink at it and
be like, well that's almost the same. But there were like actual missing
features an aspn at core from from aspn at four or five, and a
good example that was bundling and menification. That is not a thing that exists
an aspnt core. That does exist an asp dot net and it will never
exist an aspn at core. Like they're they're not any bundling and menification business.
Like before Microsoft was like yes there are are like node ways of doing
this, but you know, we'll provide a way of doing it. Now
today they're like, uh, this is a solved problem, but solved by
not us, So use that thing. And like I said, this is
a solved problem, Like why would they build their own, right? You
just go out and get the best one you can, don't You don't need
to make another one, just another thing to support. And we so we
looked at that. So anytime we hit these sort of things that there is
no direct migration path, we have to decide what is that target and state
that we want to get to. So bundling and menification was an example that
Okay, yes there are there are like there are people that solve this problem,
but they're all in the node world. Yeah, And so we had
asked ourselves, Okay, do we want to introduce this other build and asset
pipeline that is totally different than what we have today or is there something else
can have broadcha gap. So we actually went with a tool called web Optimizer,
which is very similar to the asp dot net for eight bundling of medification
but for acep net core. Okay, so if you have very simple bundler
and menification needs, that can do the trick. So we saw that like,
well, okay, maybe the right answer eventually is to use a true
bundling and menification pipeline, but for now, let's just kind of go easy
mode and do something that is solving the problem in a very similar way than
what existed on a HPNT four eight. Again, it sounds like in a
later version we can optimize us further, but for now there is menification and
bundling in a pipeline, so close enough exactly. And we saw that the
node pipelines would force us to even structure all of our assets differently. Wow,
So we thought, okay, like it won't be exactly the same.
So we even did tricks like in visual studio you can you know, right
click files and say add as link, so the file actually exists in one
place on disc. And so we did that a lot for these sort of
static assets that would we would automatically add all these folders as as links,
so that the file existed in one place on disc, but had to be
structured maybe slightly differently on either side. Yeah, it's very cool. Yeah,
that's really interesting. But and he also speaks to there are different philosophies
of software development, and you know, don't be too wound up about it,
like that's okay. Just if you're going to change philosophies, you have
to learn a bunch of stuff. It was all those sort of like micro
architecture decisions of okay, what is the shortest path to get us to production
versus where do you want to go? And is the eventual in state on
the way to get us in getting us to production now? And if not,
okay, then we have to make a decision do we take that chance
now or do we just you know, go sidestep a little bit and say
let's just get something that can work for now, because our end goal is
to have the whole app and production on Dot eight and Jimmy, I got
a break for one moment for those very important message and we're back. It's
Dona Rock's Amerchard Campbell. That's Carl Franklin Hey recording in twenty twenty four.
Who would have thunk it? Who thunk? And we're here with our friend
Jimmy but Guard talking a bit about his experiences migrating a dot net app,
a framework app, a four point eight app up to dot net core.
I guess originally targeting six, but heck, here's eight, might as well
go. There was there any real differences between six and eight? Did you
stop by seven on the way? Was that a factor? So one of
our one of my philosophies for just getting this deployed out is I I wanted
to get to production as early as possible. So for us, that meant
our very first deployment was a completely blank dot net six app that did nothing
but proxy straight over to the full down that framework did. That totally makes
sense, it does in hindsighted, but that's that is one of those like
okay, do do we need to do we have something there that does anything
or or what? And because just getting that first dot net six app required
us to do all the build and deploy pipelines and I setup, like we'll
just do that. It'll be a like a foot hold on the beachhead and
then we can start to build on top of that. So that's our first
thing out. Yeah, it's a Hello World, right, Like you got
to get there one way or there going to do that. So the fact
that you're only doing that first just you know, cuts away the other confusion
of well, why isn't that page working? Is it the page or is
it the proxy or is it the authentication engine or is it the session issue?
Like there's a ton of the things that canna be wrong. Have as
few things wrong as possible. And the question of like which dot net version
of target was also a challenging one because there's a trade off between from looking
at your dependencies what is supported on both frameworks, because your business logic if
it depends on a library that is supported on both sides, it's good.
But sometimes it's not supported to the latest and greatest framework, so sometimes you
have to upgrade to an earlier version and then migrate up with upwards from there.
So we actually had that with we were looking at asp at seven that
included a feature that we wanted to use, which was output cashing. Output
cashing was only introduced with ESPN at seven and our system used that, so
like, well, we want to use that, but then our dependencies didn't
support all the way up to there, so like, okay, do we
just like ignore some of the pages or nope, or maybe don't have output
casing for now and just wait on that until we're fully on. And then
we introduced opput caching. We actually found like someone at Microsoft backpowarded through this
new get package output casing with a label do not use this. This is
for you know. We just found like, well, we'll just go in.
So it definitely is an analysis part at the beginning to look at your
dependencies to understand what is what is possible for you to migrate to support both
frameworks initially, and maybe that's just a first step is to migrate something to
a little bit older and then now that you're on net core or whatever,
then you can start to migrate upwards from there. Well, I think I
found out a Sebastian Ross output cashing yep, and it's output cashing asp dot
net core six. Warning this package is not supported exactly, but he's definitely
done us a favor, Right, this is exactly what this is for.
It's a bridge to get to six with that feature and knowing you're as soon
as possible, you're going to move to Sabbath. Sapic cashing was one of
those things like it is it is kind of shared state, but not really
like if the two applications have two caches with the same data, you know
whatever, Like that's good enough. Yeah, it's not shared. It is
persistent, but it's not shared across pages, so really session state. And
then the next thing we hit was hang fire. That was another big hurdle
for us was to get hang fire being able to be used on both sides.
So what's hang fire? Yeah, what is that? Oh? Hang
fire is a it's a the background task runner for ASP dot net and ASP
dot net core. And in terms of uh background tasks, it's not like
thread dot start or thread dot run. It's persistent, so it's able to
effectively have like a like a queuing capability or state capturing capability. So if
I want to say, send this email, but don't send it now,
send it you know in a background whatever, but something they can actually be
retried and like remembered. So hang fire is a library that lets you do
that also does things like scheduled jobs to so like it's cron but it's all
it's all self hosted inside asp dot net and asp dot i core. And
if you haven't had the hang fire folks on to talk to them, that's
a that's a fantastic library if you want to do like async background tasks in
a more robust manner. Nice so noted. So one of the challenging things
is and hang fire you you can define cues of work to say go go
do this work sometime in the future, and then it supports all sorts of
cuing mechanisms, including sql uh. One of the cool things that does,
though, is you can say I'm in my controller class and I say go
do this work. But the work you're saying to do is to call this
function that's also inside the controller class. So it's very easy to say,
you know, just extract out a method and say just call this one method,
but call it, you know, call it offline in the background.
So it's just a more robust way of doing thread dot run or whatever.
But it's it's able to keep it, keep track of it. The way
it does this though, is it notes the class and type of the method
that you want to run and then also captures the state you pass into it
and like some blob to be able to use reflection to load it up and
then call it. But that implies that that the thing that is going to
sort of DQ and start the work has to have access to that class and
that type, and it's not something that's completely obvious unless you understand the internals
of this hand fire system. So we realize that, Okay, if I
try to start the job on the ASPNT four or five side and I try
to execute the job over on the donet core side, it may not have
access to that job code. So we have to decide do I refactor these
jobs out into my common business logic so that both sides have access to it.
We wind up not doing that. We wind up doing it to say,
we will define queues one queue for the don net four eight side,
one queue for the dot net core side or dont six seven eight side,
and then when I need to n Q a job, the on qu or
has to know where does that code live. Does it live on the dot
net eight side or does it live on the donet four five side, and
what they let us do is just say, for the don net four five
side, we will que it can it can, it can exit. It
can start and run jobs on its side, same side on the donat eight
side, it can start and run jobs, and vice versa. So I
can have dot net four eight kickoff jobs, dot net core and dot net
core kickoff jobs and four eight depending where that job logic actually lived. And
so over time we over to migrate those jobs over to dot nets eight,
but along the way not sort of force ourselves to have to refacture all that
job logic, because it was it was pretty complicated, and we said,
it's going to be too much work to try to pull all this stuff out
do some common location when today there were just private methods on a controller class.
It'd be a lot of work to try to pull those out to somewhere
else. And we realized like there were there's a lot of work to win
into getting those things hooked up appropriately. But just another one of those things
that I have shared states, shared kind of background resources between these two systems,
and I have to figure out how do I effectively get these two systems
to kind of play nice with each other over time. Yeah, and this
is all part of that bridge. But and you did get to the full
cut across. Like you said, you get to a point where you've replaced
everything, like how many how many deployees? Is that? How many interimsps?
You know? Well, so the organization that I was working with was
doing weekly deploys, and so we wanted to keep to that, like every
week we would deploy the pages and we have migrated all the way out to
production. We just didn't want to have this big bang. Okay, now
all the pages are over, Now it's time to cut over. There was
no cutover. It was just a slow, slowly like constricting it down and
down and down until the very end. I guess I didn't talk about migrating
individual pages, but that was pretty straightforward. You basically copy and paste the
code and fix the compile errors. If the dependencies weren't working, well you
go pull in those dependencies. And then if those dependencies had to be hooked
up via dependency injection, well, now we go ahead and can figure the
new DEI container to wire up all those dependencies. So it's very much incremental,
just pull things over as we went and then if we saw extra problems
cropped up, we would pull those in, but otherwise it really was just
like fixing namespace errors and copying and pasting UI code. But we would deploy
every week the new controllers and pages that had been pulled over, and even
our stories inside of Jira were every story was migrate this controller. Right,
so we knew we had a clear sort of burned down, which is one
controller at a time, just kind of steadily chopping them, chopping away at
it, until eventually there were no more controllers left, and the only thing
we had was an empty an empty application that was still deployed all the way
to production, right, but nothing in it. Well, yeah except for
the olag and controller, like the authentication that was the last one. Except
the log and controller, of course. Yeah, And that's fair. I
wonder if you sort of nailed down all the hard bits early, like took
spikes on stuff like output, cash you and so forth, or did you
find a few as you work through some of these controllers you're like, oh,
how are we going to do this? We had, so we tried
to get a decent idea up front of cataloging, and it's pretty easy to
do, like you go to the global asax right, look at your middleware,
that being what is being pulled in there this application. I was using
Owen, so we looked at Owen startup and of course webcinfig right, because
there's so much junk in there. We just looked at Okay, all these
things have features that exist an asp net core more or less. So what
is the sort of migration path? Well, we knew we were going to
get it all. So one example is hang fire. We hit that like,
oh right, we get an error running the job. It's because it
can't run the job. The job is over there, not over here,
So we'd have to do you know, okay, let's pause, do a
spike, and then we wind up doing things like well, let's defer.
Once we found that that was an issue just prioritization, we deferred all of
the controllers that did that to say, let's just do them later because we
need to figure this out first and work on some other ones that don't have
that sort of dependency going on there. That's that's legit, and it just
feels normal. But I really appreciate it about this whole conversation, Jimmy,
is that you didn't go for the ideal case on anything like, it's like,
well, that will be good enough for now. We'll be able to
optimize that later. That'll solve that one. This is an interim step and
you know, and you're going to have some glitches along the way. It
doesn't sound like it was a perfect migration. You had to fight through some
stuff now. So we just made sure that in our schedule. You know,
we didn't try to solve all the world's problems up front, Like the
big spike we did up front was just this whole YARP system of adapters because
that had just come out like a month before we started the project. I
was like, oh, this is how we can do it. That's great.
I was a frame or easier, but we had to figure out,
okay, is it as easy as we think it is? And for the
most part it was, except for like the shared state, you know,
the hard problems authentication whatever, but for the like just normal pages, like
it was even things like signalre it worked between those two applications. I was
like, wow that just as long as they can talk to protocol, that's
how signal are supposed to work. It was able to proxy through just fine
to the done framework application. Right before Christmas, I upgraded a customer's website,
a Blazer site that I had built and dot net six and upgraded to
dot net eight, and that exactly the same. I mean, most of
the stuff just worked. There was there's you know, the obvious things,
you know with Blazer, there's some big changes and stuff, and you know,
things that come out of program cs that were there before, things that
go in updating all oh my god, updating all the new Gap packages.
Yeah, that's I mean that was the very first thing, you know,
and then reformatting. But you know, as I said, I discovered some
technical debt in there. This was definitely a project that I started and started
the customer down the road, and then they kind of took it from there.
And I wasn't like a babysitter on the project, right and I'm discovering
all sorts of weird things. They just found ways to make stuff work that
come with consequences. Yeah, yeah, well, just it works. It's
great, you know, it works, but it's not great. Great.
We definitely hit a bunch of things. It was just it had been a
while since I've been in like deeply involved in dot net four eight and a
SPNT four eight. I just forgot how many things were fixed and ASPN net
core, so there was a there was so much code I got to just
delete. That was just you know, infrastructure wiring of stuff that is now
just services dot blah. I just it's just there and for me, so
there's you know a bunch of filters owen stuff that just went away and made
me so happy. Oh the webcon figure, Yeah, that just that was
all code. Now it's it was. It was beautiful. It's great,
yeah, it's it's it's profound. But I appreciate that. The core idea
here was no dead drop. Start with YARP so that you have the new
a blank new app that's just redirecting everything to the old app. And then
I mean my instinate would say, now pick the least important thing and build
it first in the new app and see if that works like a min's screen.
Yeah, so that was that's that's what we wound up doing, is
like is it was the I forget it was, but with something the homepage
is something that had like nothing on it, and we knew like that.
That first one though, took a lot, because that meant we had to
have styling, we had to have layouts, we had to have all the
dependencies hooked up. So yeah, we picked the dumbest page possible to start
with. Knowing that, okay, now we got to get like all the
all the very application company specific gumming gum you know, to glue all together.
That has to come along with that. So we're like, we'll just
pick something dumb to make it simple for the first step, because then you
focused on those gubbins, right, like that, the styling stuff, like
all of that bits and pieces, because the page is not the most party,
it's all of that, and again you could get lost in that complexity
all that Ruckus, Yeah, exactly. Gubbins is a good word. I
love that. Thank you John Skate for introducing me to that word web gubbins.
You know, my kids now say ruckus. There's all that in thereat.
It's a good word. H boy, that's it totally makes sense,
like all of these bits and pieces of that's the approach to go through the
different parts and you get to a good place eventually. So at a year,
you figure, did you take a year? Oh no, no,
no, Like it was a year of my life just dealing with several of
their apps. So we the first the one we migrated, was done in
about four months, and that was I don't know, one hundred two hundred
controllers and maybe about five hundred actions or so. But like, once our
team got the hang of doing these pages, they could just like knock them
out. It started to just become like a rhythm that they did the thing
to say that you had the we had the live you know, the living
wiki page that would keep Okay, if you run to X, y Z,
here's how you solve that problem. And then just continually have a little
micro lessons learned as we go, and they just started to really roll once
we got going. Yeah, I bet they got some momentum up, Like
the cadence gets faster and faster as you know where all the bits lie where
Okay, that's how you solve this problem. That's how you solved that problem.
Do you get And yeah, eventually there's not you know, not new
problems to solve anymore. It's just okay, we figured out all the hard
problems. Now it's just copy paste, copy, just co go time.
Yeah. Did are they now better equipped to migrate something else inside the organization?
Like I got to think this is somewhat personal mapping to the way that
company likes to build apps, so that the skill set they now have is
good for their apps, not necessarily good for everybody else's apps. Yeah,
So the next app was was a lot easier because we knew we didn't have
to prototype a lot of stuff, Like we didn't have to prototype the yard
stuff or or understand, well, how do we solve the hang fire session
problem, Like we knew how to do that, So the heame a lot
easier. If they had a giant web form system, though, then like
that's that's totally different. So if you're like Vanilla NBC Vanilla web API,
it's a pretty straight forward activity to do there. I mean, there's always
going to be things like oh gosh, they were using some controller or some
upload control that was was not supported anymore. It last was leaves, Like
in twenty thirteen, I was like, Okay, for this thing, we
need to migrate that thing first. There's always going to be those one offs.
But as a general approach, we knew this was like this was the
way to go, incremental small steps and release as we go. So,
Jimmy, what's next for you? What's in your inbox on my inbox.
Oh gosh, well it's same old, you know, same old, more
modernization, more migrations, more more up upgrades to folks for doing this kind
of thing. So like I kind of learned it once and so I want
to help more folks be able to do this in the future. You could
speaking anywhere coming up. I am albeit to NDC London this month, next
month with all the cool kids. Yeah yeah, I guess, and then
I'm taking a break. Maybe maybe I'll be at the MVP summit. I'm
still deciding in March, take a little break and then do some travel next
to aprilcasts awesome, very good. Well, it's been great talking to you
as always, and I'm happy New Year and we'll see you next time.
To your listener on dot net rocks. Dot net Rocks is brought to you
by Franklin's Net and produced by Pop Studios, a full service audio, video
and post production facility located physically in New London, Connecticut, and of course
in the cloud online at pwop dot com. Visit our website at d O
T N E t R O c k S dot com for RSS feeds,
downloads, mobile apps, comments, and access to the full archives going back
to show number one, recorded in September two thousand and two. And make
sure you check out our sponsors. They keep us in business. Now go
write some code. See you next time. You got jud Middle Vans time then