How'd you like to listen to dot net Rocks 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 net Rocks patron mug. Sign
up now at Patreon dot dot net rocks dot com. Hey Carlin Richard.
Here. As you may have heard, NDC is back offering their incredible in
person conferences around the world. DC Porto is happening October sixteenth through the twentieth.
Go to Eddcporto dot com to register and check out the full lineup of
conferences at NDC Conferences dot com. Hey there, this is Jeff Fritz,
the Purple Blazer guy from Microsoft, letting you in on a little secret about
my friend Carl Franklin. You know the guy who started dot net Rocks,
the first podcast about dot net in two thousand and two, The guy who's
been teaching Blazer on YouTube since twenty Yeah, that Carl Franklin. Well,
Carl's joined up with the folks from Code in a Castle to teach a week
long hands on Blazer class at Are you ready to get this at a castle
slash villa in Tuscany. It's sort of a luxury vacation with Blazer learning built
in. Carl's calling it the Blazer master Class. You'll learn Blazer from the
ground up, finishing the week with the ability to build and deploy Blazer applications.
Since the training happens for only four hours in the morning over six days,
you can bring your significant other your partner with you and you should right
that this part of Italy is absolutely beautiful. There's so much to see and
do and and Larry and Marco from Code in a Castle are organizing daily activities
both at the castle and in the area. The castle is in the Marema,
a less touristed region of Tuscany, offering both classic Tuscan hill country as
well as easy access to the Etruscan Riviera, with sublime local food, wine
and olive oil around every corner. Breakfast is included every day. There will
be two communal dinners at the castle book ending the experience, and most other
meals and all activities are included. And did I mention you'll learn Blazer in
person from Carl Franklin Listen. Space is limited and for very good reason.
This is quality training in a beautiful setting. Go to code in Acastle dot
com slash Blazer twenty twenty three. That's bla z o R two zero two
three to take advantage of this amazing opportunity to join Carl in Tuscany for an
unforgettable week of La dolce vita while advancing your programming skills in this important new
technology. Welcome back to dot net and rocks. I'm Carl Franklin, and
I'm Richard Campbell, and Jimmy Bogart is here. We haven't talked to him
in a while. It's gonna be fun, fun, fun, I say.
But first, Richard, how are you you all moved out yet?
Just about moved? Yeah? Final, you know, of course we're recording
a couple of weeks in advance, sort of the last things we're moving.
By the time this show publishes, I think we'll be a week away from
handing over the keys and living on the coast full time. So we've done
the slow move like we've spent weeks at it, just taking truckloads up each
week with our pickup, and in some ways it's been very therapeutic because bit
by bitness. House feels less and less ours. Yeah, you know,
when you take all the stuff off the walls and you're emptying out rooms and
stuff, it just sort of becomes a house adminally, it's a house we
built back in the day. But and it looks like it needs a rena
now, like it's been fourteen years since we built it. So the cabinet
needs to refinished and the floor should be redone, and I'd replace that carpet
and I paint those walls and it's not my problem. Somebody else is gonna
own it three four weeks, So that's that. I had my uh Pop
three zero Studios opening grand opening party last Saturday. Yeah, it's not really
done, but it's pretty close. Let's be clear. Nothing's ever done.
Nothing's ever done. It's like building a software apple, you know, building
an app. Is it done? What is done? Well? There there
is a definition of done, and it's not there yet. Basically, we
have the you know, the walls are great, the floor is awesome,
the tram is done. They are conditioning unit is in and half of the
room has sound absorptive ceiling tiles on them and they're hung like they're custom made.
They're hung so they're two inches from the top and that means that sound
gets trapped above them as well as below them. But only half the room
was done in it's just because we just didn't finish that and we had to
had to pick a day. So I mean, can you record in it
yet because you kind of need that stuff? Well I could, but I
don't want to move everything in there until all of those panels are up because
everything will be in the way, you know. Yeah, yeah, but
it's very exciting. You know, we've got that nice wooden floors and they
need to be refinished, but you would never do that in living it like
it's such a it's such a mass. Yeah yeah. And so the one
chance the new owner is going to get to redo the floor is you know,
in this window when we're out before they go in. It's like,
you should do this floor now. Oh the joys of building and tearing down.
But it's funny, my reflexing, this place is no longer so much
my place, and it's a place I would renovate and how we'd fix it
up, like the things that it needs, because after fourteen years since we've
built it, it just like it needs things. Yeah, sure, well,
let's get things started with better no a framework or all the crazy music,
you know, as if I didn't need another project, what are you
doing? I decided to start a new little YouTube and maybe even TikTok show
called the Blazer Puzzle. Okay, okay, So every week and Jeff Fritz
is going to be doing it with me. Every week, we're going to
create a little demo, you know, a little Blazer application that you can
download and either it's either going to be a puzzle, a coding challenge or
find the bug kind of thing. Why doesn't this work? Can you make
the architecture better? Just something very simple, right? And then people email
me their answers and I'll pick one at random from all the correct answers and
send them a mug, A what mug you say, a Blazer puzzle mug,
so that they don't even really exist yet, but they were. I'm
sure they'll be great. Yeah, sure it would be great. And the
only way you can get them is by answering them correctly. So that's what
I've that's what I'm doing right now. So it will be at blazer Puzzle
dot com probably by the time you read this. And I hope you have
fun with it. I keep thinking about actually making a Blazer puzzle, Like
what would that app look like where you had a bunch of pieces and you
could move them around. Oh yeah, yeah, it's more like a puzzler.
It's more like a gotcha solver kind of thing. Yeah, figure stuff
out. Yeah, I kind of like the idea of a you know,
a picture of you in a different picture of Fritz and the logo and then
it breaks into puzzle pieces and falls to the bottom of the screen. You're
not far from the actual test video that we've created already to introduce it.
It kind of does look like that, good guess. Yeah. Well,
it's also also you know, it speaks to the fact that I didn't don't
have an original idea to save my life, so I'm not gonna get there.
You know, we had to. We had to fall in fall in
love calling you got it. You've got the domain name. You pretty much
dictates what you're gonna do pretty much. So anyway, that's it. Who's
talking to us today? Richard? I grabbed a comment off a show eighteen
fifty two which we did just back in June with Sean Walker, and we
were talking about going full time and open source. Yeah, you know,
just the sort of thing Jimmy Bogar, we'ld never do. Never. But
we had some great comments on that show. And I mean, it's really
fun to talk to Sean too, because he really came in it from a
yet another angle. As we keep exploring this, what does the open source
ecosystem look like today? And I'm gonna I'm gonna presume this is a pseudonym
because it's q r y s, which to me reads like queries, you
know, except for a distinct lack of vowels. Well that why doesn't seem
like a vowel in necessary? So Queery says, hey, thanks for the
great show. I can confirm that for companies it's really a hurdle to donate
to open source projects, even if they use and appreciate open source tools and
libraries. Like my small employer, which is only about twenty people. However,
we have now I decided to handle it this way. Each year,
employees can nominate their most valuated or appreciated open source project. The one that
eventually gets chosen gets a one time donation of about a thousand Swiss francs.
I just checked that's like eleven us. Okay, I think it's good service
one example of how to overcome the mental hurdle for such payments. Because it's
only just once a year, they are somewhat justified by the company as an
organization, and the company might even advertise this, although we currently don't.
Yeah, I don't know how you'd advertise that well, other than that hole
wearing your culture on the sleeve. And we support open source thing. But
you know, a twenty person company committing a grand a year to an open
source project, that's pretty legit. Yeah, it's legit. So Queries,
thank you so much for your comment. I don't know that's your name.
I'm pretty sure it's not, but thanks anyway, And a copy of music
co Buy is on its way to you. And if you'd like a copy
of music Cobey, I read a comment on the website at donet Rocks dot
com or on the facebooks. We publish every show there, and if you
comment there and everything in the show, we'll send you a copy of music
Buy. And you can follow us on Twitter if you like. But the
real fund is happening over on Mastodon. I'm Carl Franklin at tech hub dot
social and I'm Rich Campbell at mastadon dot social. Send us a two and
we might even read it. Hey, let's bring back Jimmy Bogard, shall
we? Jimmy is the creator and maintainer of the popular open source libraries Auto
Mapper and Mediator That's Media t R. Jimmy's an independent software consultant based in
Austin, Texas. He's received the MVP Award every year since two thousand and
nine, and he joins us again today. Hey, Jimmy, how are
you doing? Okay? Like Tony'll earlier, just trying to survive in this
horrible heat you've having here in Austin, Texas. It's it's miserable, like
can't walk the dog, can't do anything yet, it's just dangerously hot,
right, like not, it's not even funny. It's just yeah, there's
like don't go outside between like three and sexs. Just don't. Yeah.
Right, you start to understand why desert cultures have a siesta, right,
because what else are you going to do? You mentioned trying to live without
AC in those conditions? Oh man, Yeah, get a get a fan
of a block of ice and good luck. Yeah, Well, the last
time we talked to you on the show was twenty nineteen. It was too
long ago, June twenty nineteen. Are we saying to garls I got on
today? It's like, you know, we don't talk to Jimmy often enough,
and the those the before times it was yeah, when we went to
offices and all that stuff. Yeah. Well, anyway, we were talking
about messaging architecture and I can't remember if we talked about media. You're probably
working on it at that time, but it wasn't the complete focus of it.
But why don't you start us off with the mediator pattern? What is
it? Why do we need it? Sure? So, I think just
as a context of where this kind of came from, it was a kind
of an evolution of us building larger systems and having a dealing with the complexities
of just the kind of busines, this logic and code we're having to manage,
and so the j the gist of the mediator pattern is that if you've
got some like like UI code or something that is needing to interact with some
services, instead of you trying to talk to those services directly, you go
through sort of a middleman. And the middleman is that mediator and so instead
of you like depending directly on those services that are doing the work for you,
you kind of package up what you want into a request object, you
send it to the mediator, it dispatches to the handling logic, and then
finally returns yet response. So it's a little bit different, but kind of
solves the same problem as MVVM. Right, A view model kind of does
that, but it doesn't have as explicit in architecture, Right, is that
what you think? Yeah? Exactly, these something these kind of they do
kind of compliment and go with each other. I mean, especially MVBM,
those those those things you're talking to are also stateful and then you know you're
receiving events and communicating from the UI. When we're using this mediator pattern,
where we're usually in the kind of a more of a stateless land, it's
like a web NBC sort of place where the UI or the browser is already
sending this request and receiving a response back. And so this pattern was trying
to take it sort of one level below that and kind of get rid of
all the UI cruft and response codes and just say, well, what is
like just the sort of pure data end data out that we're dealing with on
all the different requests in our system, but it solves the same kind of
problem, which is tight compling. Yeah. I mean we we're always trying
to find kind of the holy grill of the pattern that will solve all the
complexity issues in our codebase, and I mean, nothing ever solves it completely,
but that's what we're looking at. Like we were using NBC and this
is like early early days of asp net NBC classic, I don't what you
call, like the last one, and we just saw like our controllers were
getting big, like well, what do we do now? Or do we
put this junk that's piling up here? And so that, you know,
a lot of those kinds of concepts and ideas emerge from just dealing with these
big controller classes, like how do we what do we do? How do
we deal with this sort of stuff? Yeah? What I usually do is
make a some sort of manager that I can inject into the controller so the
controller merely passes on and returns data, you know, and those managers,
I guess in the mediator pattern, those would just be objects that you send
messages to and get messages back from. How does that work with a controller?
Yeah, so we we started that. We started that exact path as
well, where we had these you know, every controller like you know,
I don't know, invoice control or had the invoice manager that had the business
object and all the all the NBC controllery stuff, action results and HP contexts
and those webby sort of things. Those are on the controller. But once
you got into like the pure business logict, I'm you know, I'm passing
data to something and then it does the work and it gives me some data
outs. We started that as a as these manager classes. Now suddenly those
manager classes started to get big as well, right, and then each of
the methods on the manager classes was tied to like directly tied to a single
action or kind of HTTP endpoint on the front end, right, So you're
not really gaining any decoupling, you're just moving it into another class. We
moved it into a different class. And we also noticed that this was in
the days of subversion, so like merge conflicts were a thing that we had
to worry about. So we are also having this issue that if you know,
we had new features coming on to a set of screens, then multiple
developers were working in these manager classes and having just merge conflict, and we
went back to the sort of the original sort of solid design, and there's
that the eye and solid was the interface segregation principle, and then general ideas
there is that you if you have an interface with multiple methods and they don't
really have much to do with each other and never called together on the same
sort of requests. We found that each of those manager methods would only ever
called with one of the controller actions, right, So I thought, well,
even though these all have to deal with like voices the logic inside of
there, it really don't have anything to do with each other. They're just
all globed together in a single file. So our first step was just to
remove each of those manager methods and sticking in its own class so that it
just was living by itself. And then if I needed to change the one
action, I had one place to go to for the business logic of that
one action that was separated from the UI, but also separated from the logic
of other requests. But you were also talking about the merge conflict part of
this, but that separation and then because it was separate file, if you
I'm trying to think about it, did subversion make a difference there, Like
is get hub somehow better it merge conflicts. Get is better because you are
able to do a three way merge. You have what you both started with
and then like where you both ended, right, and Subversion you don't don't
really have. You only have like just constant, constant headaches. So part
of that was just the reaction of that, because I mean it kind of
hurts you in your heart when it's like changed the way I do my code
because of my tooling. Right, Oh there's I mean there are other issues
as well, like those are the old days, the horrible CS project merge
conflicts as well. So just like merge conflicts, Like, part of our
thing was like how do we separate the workouts of people working on features so
they're not stuffing in each other's toes? And so we started that thing of
just like, well, just split the manager into multiple methods and then each
methods in its own file and class. And if I have to change the
business logic for that one page, I'm not affecting anybody else. Nobody else
needs to know, you know all as well. I'm also reminded and I'm
sure if this many times is that every app has ugliness in it. It's
just a question of do you know where yours is? You know, like
you're gonna have to put some ugly somewhere, So how do you wrap it
in a relatively tidy package that people can deal with as spraying it all over
the whole app? In this case, you trade it off these giant manager
classes for lots of lots of little objects exactly that now you have to manage
you having to manage something. Yeah, we because the logic has to be
there, and that we we thought the idea of like having these managers as
well. It was like, well, we can now share logic between these
different things. But that was a you know, double edged sword. One
side of the store is actually much sharper than the other. Yeah, cut
us much worse because we found that if we changed this logic that were shared
amongst multiple things, like suddenly I could have these unintended side effects. So
we were adding new features to the system, We're like, Okay, I
got to spend much more time figuring out how many I'm gonna make sure not
breaking anything before I'm able to just write code. So that's kind of another
side effect. We're like well, don't like, don't make the first thing
you're doing sharing code. Make that be the exceptional case where you know it's
after the third time you've copied and pasted that logic like, Okay, maybe
this is something we should share but not share, but I'll do it up
front. So the mediator pattern came into play. Like, after us making
these like single files, we took a step back, like these all look
very similar, but they're also different and their own like not like they're also
different for no reason whatsoever. So we were looking around at the time,
this is also the time that Greg Young was coming up with this whole like
CQRS concept of like stepparing out read and write objects, and so we looked
at these these classes like, well, this is doing that. It's separating
out like every request from each other. So the logic is the separated out
and so we we settled on this. We flipped through the old Gang of
Four book like there's got to be a solution for this, right And one
of the few times that I've looked in that book and actually found something useful
was like, oh, instead of me having these like everything is a one
off whatever, I can have something mediate sending this request down, and so
instead of me depending directly on all these individual manager classes, instead I depend
on this one mediator class and I send a request for something, you know,
I request for data, request to do some work, and then I
get a single response back, and those individual manager classes got refactored into individual
request handlers from that mediator itself. So it's just a very natural kind of
refactoring progression for us to arrive at this pattern at the end, and you're
saying that you send a message and get a response, but it's not asynchronous,
is it because you're in the web context here. Yeah. I even
hesitate to call it a message because it doesn't have the traditional characters. There's
no head or there's no package or payload or whatever. So it's really we
called it a request objects. So it's a request dto if you will,
and I get back a response another dto or data transfer objects. We want
to make this very clear, like I'm sending kind of pure data in and
I'm getting pure data outs synchronous, and for exactly it's all a synchronous,
it's all in process. We're all just just trying to do like give us
one level separation between the thing doing the work and and like the pure kind
of request and response objects in and out. It's very pure data objects.
Yeah, you're also abstracting the transport off of that too. So if you
did want to do a messaging infrastructure or a saying systems and stuff, I
don't think it would be that big of a deal to support that. No,
but okay, so there are I wouldn't say competitors, but some folks
have been done like alternate implementations in this pattern and it becomes more formally realized.
There's another version of this kind of thing called a command dispatcher, and
I will go too far into it, but it's like a whole thing of
like, well, if you're in the business of like doing this whole uh,
you know, I don't care if it's a sync or not. It
could be durable or non durable messaging. You kind of go off on that
land. But I, on the heels of my other open source project,
Automapper, never try was ice strive to make this library have as few features
as possible, because because I realized like every new feature I added, I'd
have to support for years. I don't want to do that. I don't
want to do that anymore. But let's make this as dumb the future main
factor ff of this, Yeah, like I really swung the pendulum. I'll
learn my lesson there. So this was like I wouldn't do that. There's
a couple of reasons. One is, if you look at it from a
user experience perspective, there's a stark contrast in the expected responses of an asynchronous
message versus a synchronous one. If I'm on a screen and I clicked the
button and it comes back to response saying yes, I you have submitted the
form and I've received it. Now you can see the results of that on
your screen. If it's asynchronous and it sends message to a Q, there's
no guarantee of when that work can be done, So the logical response you
get back is like we got your message. It'll be done sometime in the
future. We don't know when, but like thank you for your request versus
don't call us, we'll call you exactly. So like that the invoice example,
I click approve invoice, I go back to the list of invoices and
it shows approved. If I send them a submitted request to approve the invoice,
it'll just say we have received your request, but that invoice is not
approved yet. It's approved some time in the future, So don't I don't
try to swap those two up because it has a drastic impact to the user
experience. Yeah you could, though, You're just like I want if you
see folks using this pattern and they're like, oh yeah, and I can
swap in, you know, as your service bus, I'm like, wait
a second, that's going to have a huge impact on the UX because now
they can't they don't see the results of their actions. So just be careful
that you don't try to do that sort of thing. Right, So what
does the Mediator library have in it that gives me more than I can,
you know, do just creating my own objects and interfaces to abstract these things
away, saving that thirty minutes of time, I guess. I mean even
when I created the library myself, I didn't want it again. I was
coming off of like autumn apper annoyance, and I like, I don't people
want all this stuff, and now they're asking me off for these features and
I don't want to, you know, say yes to everything, and so
there's like I want to create this library to begin with and I had copied
and pasted that code to like the fourth project and our consulting company and filing
a boss is like Jimmy, just like create a library for this, Like
this is just create a new GET package so we don't have to copy and
paste this code and if we do, like have any changes or features whatever,
then like everyone benefits at our our company, not just like the next
one that gets copied and pasted. So that was kind of like if you
copy and paste code from the third clients, then maybe you should make up
a new GET package for that. So that's effectively what happened qualified, Yeah,
so that they kind of like it started out as very simple and like
hundred lines of code that could be done anywhere, and really most of it
was just like you were using dependency injection containers. So how do you make
sure if I send a request thing down that it gets dispatched to the right
object while we're using dependency injection to find the right thing to dispatch? Two,
that's annoying code to write to like hook those things up. So that
got wrapped up into the package as well. So just started out like that
was just pure here's the code I've been copying and pasting over and over again.
But since then it kind of graduated to like, Okay, how are
people using this? How can we gather those lessons learned and then apply those
lessons into this library money. You've got tens of thousands of people using this?
Is this one hundred and forty million downloads? Like I didn't know.
I didn't know that many. Yeah, I'm just looking at the geth hub
dude, it's like, yeah, fifty four thousand, Yeah, like that.
These are big numbers. Yeah, I mean a lot of them.
Are you know my Azure function bots, you know, pumping those numbers in
the background. But I'm sure a few of those are. Are you running
a hundred million Azure bots? I just wanted to know, because that'd be
cool, be very cool. Oh No, I don't think the MVP perks
will cover that many. Yeah, that's exactly might blew your budget a little
bit, just a little Just looking through the code, I mean, yeah,
there's some really really cool stuff here. And I love the fact that
you're using generics and even out types out of tea. Oh, I don't
remember the difference, Like there's it is using the variances. Yeah, of
cod and contra. But it looks pretty I mean, yeah, there's some
stuff in here, but it does look very simple, and that that's what
makes it good. I guess, huh. That was the idea is because
again we're trying to distill down like what it's kind of the essence of our
systems, and it's like you send a request in and you get a response
out like that's I mean, I'm I'm dealing with web apps most of the
time, right It's it's all HDP request response. We're like, well,
how can we take that kind of one level below that, which is get
rid of the status codes and you know, streams and junk like that,
and then it becomes a pure like I send a data request in and I
expect to get a data response out. And that made it also really easy
for us to test our systems. So we we we shifted our testing.
We used to have these unit tests. They were all unit testing our controllers
then like mocking those managers out or manager dependencies, and it was really hard
to understand what's going out of the system. So from there, with this
mediator pattern, we had all of our tests go through this like request in,
response out, which made it made our tests now very kind of simple
to understand. I pushed data in, what is the data get out?
And what happens behind the scenes I don't not my problem called the sort of
procedure or what I don't know, and both sides are testable that way,
right, you could have a simple invocation to chest to back end part of
that too, exactly. So we we we had this big shift from oh,
you know, the old testing pyramid with like the bottom is all your
unit tests and then you have like like an order of magnitude fewer integration tests.
We woud up kind of flipping that where we started out with all of
our stuff being integration tests because I was like, the way I absolutely knew
the system work would be to send the data request in and validate the data
request out and if that look good, I don't like that's and then okay,
if there's like you know, more granul a lot I want to you
to test, we can do that. But then, like we our confidence
or system just doubled because we knew like from this very you know, pure
request response a level, it was all working the way we expected to.
It's almost assertion like it's like I send you this, you give me that,
you said, I see you this, you give me that. If
you can do all of these things green light exactly right, So it could
just help simplify. Yeah, just the the window into the actual logic inner
system became very uniform and very focused on each individual request from each other.
All right, So I see that you have notifications in here, which raised
my eyebrows a little bit. So notifications typically are asynchronous to me. And
then I look in the code and you have a wrapper class for a synchronous
notification handler. What on earth is that? So one of our like one
of our guiding principles when we're trying to build these kind of systems is like
okay. For the request and responsition system, it was always one one with
the kind of user interface though one request in, one response out, and
those were designed specifically for each individual kind of web end point in my system.
I didn't share those requests, didn't share the responses typically, but they're
always like one to one. I send one request in, it goes to
a handler through the mediator, and to get a response out that is tied
to that. But there were still sometimes that I did want like sort of
one to end so if I have a kind of request going out, it
may be going to multiple different handlers to be able to to do something with.
And then one example, one kind of good example we had is if
I have a set of business logic in my application, and if I'm doing
like DDD, then that's that's my quote domain layer. But if I want
to affects, if I want to affect change in some other part of my
system or some other system altogether, I don't want to necessary put that logic
right there, because that's kind of imperative go poke this other thing over there
to do the work. Instead, I would like to say, well,
this thing happened. I want to notify other folks that this thing has happened.
And then however they like to deal with it, it's completely up to
them. So it's still a synchronous sort of handling. That is, we
I'm invoking those notification handlers synchronously. It is a sync in the C sharp
sense, but it is synchronous from the I am awaiting the response of that
handler. Okay, but then when we're doing in those notification handlers, is
then like, well what am I affecting change another system? Like calling another
web afi am I then actually taking that notification and dropping it on a bus
as a service bus, and then notify actual external systems. I could do
whatever I want to like, instead of me having to directly invoke those systems
from my business logic, I can raise a notification and have that then translated
or done whatever I want to the outside world. So it's it's almost just
like another word for request and response, but it indicates that we're calling another
object that might be in an entirely different domain or a different stack exactly.
So it's it could be. I kind of think it's like like the regular
sending the request is a you know, one to one. This is a
one to many. But I really wouldn't call like pub sub because you're not
subscribing to things. I mean literally, all that's doing it is like going
to the container and lasking for all the different notification handlers of this notification and
then calling all of them like the very stupid thing under the covers. But
it gives you that decoupling of the handling of what like what to do with
that versus imperative like they'll flip this other bit. Yeah, I'm just saying,
well, my bit was flipped. Who Ever wants to do something else
with that is completely up to them. Very cool. Thanks for clarifying,
And gentlemen are going interrupt for one moment for this very important message, and
we're back. It's dot at Rocks. I'm Richard Campbell. That's Carl Franklin.
Hey, talking to our friend Jimmy Bogert about Mediator. I just know
it's like mediators in your gid hub repository, Jay Bogart, but automapper is
not. Yeah, I don't know. Why don't you know, Jimmy.
Oh, I mean, like automapper wasn't my gid hub and then we had
then we're like, okay, well, there's multiple other kind of libraries related
to it. It was easier to put those under an umbrella of the realization
versus my personal one. Where's mediator, Like there's not there's just that and
I don't want anything else. It's like I even recently classed down there was
an extension for the Microsoft Dependency Injection container, right, and I noticed that
the downloads of that were almost identical to the downloads of the main library.
So I'm like, they're always taking it. Why I have a superpository?
So even classes, there were two and now there's one. It's like the
Highlander sort of rule. Now there's one. Yeah, where I see an
automapper, you have stuffer any framework stuff or oh data, and it becomes
a nuisance. So rather than have them all listed mixed in with everything else
and getting issues because it can't find stuff. Right, but you know,
this is good. This is like a lesson in how to evolve things that
become too complex. That's just that's my goal here. I'm like, I
don't want any more headaches and open source head eggs. Like then just kind
of a forcing function that I can't make it more complicated. It is a
It is an interesting point that this opinionated approach to software comes from experience that
the more stuff you build, the more you realize, you know, I
kind of really want to make this thing. Just do this thing, and
if you need to do something else, you should use something else. I
was another huge I mean that's from the design of this liber mediator, the
whole Like I copied and paste the code several times, like automapper did come
out of a project, but after it was done. In that project,
I added so many features that I never used personally right, which is super
fun. When someone comes with a bug and I'm like, oh, actually,
I have no idea how this is supposed to be used. I just
kind of like, you know, chin scratch speculation, the one this might
be cool for somebody, and then the buck comes in and like, well,
I don't know if this is correct behavior not. So Mediator is like
purely now born out of I don't add features unless I have some immediate needs
on clients or projects whatever, and then you know, if there's something that
I think it may need, then like I really have to make sure that's
I'm not well. I think the main thing is is somebody going to use
it well, depend on it in a meaningful way and more, and actually
think and exercise it enough that you know that it works correctly. Right.
I have to be super careful too, of changing the design of anything in
there, like automapp or I really didn't care too much about breaking the API
from time to time because I just devour devs. I'll figure it out.
You're fine, yeah, exactly. Mediator is like I live through the pain
of me breaking my own API. It's like you beat yourself up. It's
like a really super super careful about those sort of things, but I mean
it just happen from time to time, Like, oh gosh. One of
the bad ones recently was I had a cancelation token support, which I should
have had from the beginning, But like adding an extra parameter to an interface
where you have like a hundred implementations and on a project, I need to
get really good at reg x to like make this simple myself. Yeah,
no kidding, but well, this is always that thing of realizing how I
missed this feature should have been in there in the beginning. When do we
commit the pain now or later? I mean, you were just talking about
generics we had. I did a change where I added generic constraints because I
thought it was not because we needed it, because I thought it would make
the code more correct, but instead just like pissed everybody off because it didn't
add anything and it just broke stuff. Like it just silently broke stuff.
If you if you add the constraints, it's like suddenly it just won't it'll
compile. This is my mistake. Like it's still compiled, but just didn't
work, and nobody knew why. It's like, well, whoops, don't
do that again either. Yeah, then, and that's just the the classic
architectural problem, right if like do I do I need this now? Well,
I you know, I'm probably not going to need it later exactly.
Like it's really hard to anticipate. At the same time, it's like and
you always regret it. It was like, oh, I do need this,
and I didn't do it back then, and now it's going to be
harder to implement. Yeah. One of the fun things about this project though,
has been it that just like seeing how the like the crazy ways people
try to use this thing, and like half my issues are like just don't
don't do that, Like you're you're you're well passed the boundaries of what I
would consider like appropriate useless library and like if it's if it's painful, then
like maybe don't do that, right, Like you're you're abusing it. I
just don't hurts when I do this. Don't don't do it. I love
it. It's it's so much fun. Do you actually work much on automat
or these days? Uh, It's like my open source work is almost like
it's ninety five percent determine on what my clients are needing at the time.
I just don't I'm not a hobbyist OSS developer. I mean I spend time
like up doing updates and like issues. But I can only code for what's
in front of me. And if the people in front of me don't need
something done, then like I won't. I just won't spend my time doing
something speculatively because I had so much. Yeah, I mean, do you
do need recreational coding these days? Really? Are you just working? I
mean, I this this coding examples for like conference talk scout as recreational.
Yeah, I guess that's as close as you get in the end. You
know, we don't make a living from conference talks. They have some benefits,
No, I mean I don't, not not especially, It's just I've
got you know, children now, so like they Yeah, you're your hands
are plenty full, friend, and I get that. And it is interesting
you see how we cycle in our lives between these different things. Yeah,
you know, part of selling this house is I a whole lot of home
assistant in this house and I am been writing a manual for the new owner
to live with home assistant and just just got to take all that equipment with
you, Like these are my switches I would break the house, you know,
and and they actually you know that the realtors sold the house on the
back of some of these automations, you know, the whole just walking and
walking in the room and say play jazz and it play jazz like they like
that stuff. How do you leave it behind? By the way, And
this has totally got nothing to do with anything. But so I've now made
the list of all of the different accounts I have to migrate, and and
it's a dozen. There's only one one that has a formal transfer ownership concept.
Well you can actually say, hey, I'm selling this equipment to someone
configured as it is. It's so NOS the audio guys. Yeah, so
yeah, there's a bunch of so nos integrated in the house, works really
well, no reason to move it. Why would you break that? And
they actually have an infrastructure a setup where it's like give me the new account.
There they agree. Stuff leaves your account, but you keep the configure.
You know, I got a lot of stuff tuned up perfectly with the
house. You don't want to lose any of these configurations. None of the
others have that. Some of them are. Some of the others. You
can create a new account to it and then move stuff over to it,
but not really on migration and I'll just delete myself out of it. Some
of them are like, nope, start over. Yeah, that's just painful,
not your problem. Sorry, total digrections. Stuff that's on my mind
right now. Yeah, that's okay. So we're not going to see in
Copenhagen, I see, uh no, I got accepted to they sat Louis
dead upcomp so show Yeah, I've done that. Show might see the Cardinals.
Who knows it's time? Yeah, without a doubt. Do you do
talk some media or I didn't even check. They're always tied into the problems
I was trying to solve because I've done I I've been no talks on automapper
or mediator. It's always in service of like we came up with this tool
to help solve this problem, and the problem we were having was that when
I talked about earlier like these controllers are too big, we need to split
things out. And so when I talk about like architectural concepts that that helps
solve, it's really like, oh, and if you want to make this
easier in yourself, that you don't have to like figure all your container junk
Yeah, there's this thing here that well just like kind of skip past that
part makes that piece easier, which I mean makes a lot of sense.
Right, that's supposed to be the way that open source projects emerge, right,
and how they get maintained. And I think it's wildly credible too to
say, hey, I don't talk about my project. To talk about my
project, I talked about a problem and how I solved it with something that
became a project. Right. The other thing we noticed as well others,
another just kind of funny aside is my projects seemed to unearth more bugs and
Microsoft libraries than anyone else I know. So like Mediator has exposed a lot
of bugs and the MICROSOFTDI containers because if people just doing stuff that I wasn't
quite expecting, or things that like other containers support out of the box,
but like Microsoft didn't need it, so they didn't build it. The same
thing happened with Automapper automapp prizes like link supports, and we have uncovered more
bugs and enerny frameworks link Provider than anyone else I know, because like we're
just building these crazy link queries behind the scenes and shoving God over to the
you know, to make sequel and they're like, oh, what is this
you just gave me? Like sorry, yeah, generated link query to become
a generated sequel query doesn't always go. Well, is this whisper stuff?
Right? I whispering? You're hear you whispering easier? Is it the same?
I don't think it's the same. But when it works well and again,
it's like, and you probably made the product better in the process,
because like, this expression should have worked. Why didn't it work? I
mean I had a I had a poor request open on the Microsoft TI container
that was finally merged after I think four and a half years. Wow.
And that's after going through like I think the third repository because they went through
their like several consolidation efforts, so like this issue had to keep getting recreated,
like and first over here and first first one over there. But it
was something to do with the variant stuff. They had a bug in there
how they were doing generic variants and it broke scenarios for us, and it
was a valid scenario to me. So people are doing this thing with the
notifications where they would have something like a invoice approved notification, but then they
would make that notification implement interfaces like I auditable or I loggable, and so
they would look for all the auditable notifications to make sure those got audited.
But something broke with that, like it couldn't handle that like kind of level
of indirection. So it stuff like yeah, I don't know if it's a
valid use of container, but it should work and it doesn't. So and
they try to ditch you more than once by moving their repository off this way
for a repository shell game area. If we move the project, maybe he'll
leave us alone. None of the DII container authors like have many good feelings
for me because they keep getting issues open and their repositories to support something that
people are doing with my stuff. And like, right, I noticed that
you have a face for I stream request, so you're, oh, that's
a new one. Yeah, you're embracing streaming. So so I said it
was simple, but you have these like every time you think I need to
write something to support oh what about this, I look in there it is
okay. That was still one though I actually had a real world project scenario
on that one. Then I wouldn't put it in if I didn't actually need
it, because it was like you know, with a regular request response.
When you get the response, the server is done, right, it's done
doing the work, and you get this data object that's that's finished. Well
you can, yeah, you have to yield it at some point. But
the stream stuff was like, well, you're not really You're getting an eye
Oh god, I and stream innumerables innumerable, I forget the name of the
interface. I A sinking numerable. That's the one, thank you so much.
So yeah, it's like it's not done yet, and even like innumerables
aren't quite done yet, like I'd still connected to the server potentially. But
our use case was we were doing on demand real time et l from a
huge on prem database to like our new micro service database in the cloud,
and it was too big and complex to try to etail the whole database is
once. So we said, okay, the first time we user hits this,
we're going to stream the data from just their their data into our system
so we don't have to do everyone all at once, which should just be
too complicated. So we hooked that up to another library with mind. We
don't have to talk about it, but it's one called bulk Rider, which
is basically linked to Sequel book copy. That's a nice little tool. It
will innumerable a book copy operation. So I'm only loading in like n number
of records at a time using this equal bolt copy library the Microsoft has cool
so limit. I could stream you know, thousands or tens of thousands of
records through link in etl and like you know mill seconds through this process as
well as like transforming as I go. But at the end I needed to
stream it out through an API to our server. So we thought, well
we Microsoft now has gRPC support, which also has async or innumerable supports,
so we're able to stream all of that through this mediator pattern all the way
out to the consuming clients to be able to stuff it into the database instead
of having to you know, load tens of thousands of records at a time.
It's only you know async in numerables the whole like async numerable turtles all
the way down. It's that's really where that came from, was like you
know, all these Microsoft stacks, asp net core and their g RPC stuff
now supports async and numerables. We're not keeping not loading up all the results
in memory. It's streaming back out to the clients and so this was just
to support those kinds of scenarios. And also in that list of things that
you could support that you have API contracts, in gRPC contracts, but you
also have Blazer with no sort of any any you know, explanation as to
how or why you would support Blazer because that's all UI. Yeah, it
is. So in the cases where you do have this kind of like I
don't want to stick everything in the Blazer page. I want to like shovel
it off to like something else, then it kind of goes into there.
But it is just cross this boundary because I've had folks like another example is
like Razor pages or Azure functions were it's already kind of contained in a class,
So like why what what advantage does it give you? So for me,
like I don't use this pattern and Azure functions because I'm like I'm already
I'm already at the scope of a function. Like having another level of directionn't
really do a whole lot for me. All right, So you meant to
say Blazer server there please are server? Yes, thank you? Yes?
All right? So yeah, you're on the server side. Yes, you
have access to the database and you don't have an API layer, but you
still have some kind of manager in the back end that's going to do stuff.
This is a really good solution for that. Yeah, yeah, cool.
But when I into these, when they get to these sort of functional
frameworks, I tend not to use this because I'm like, I'm I'm already
there, one class one method, good to go. Yeah, you don't
need to add complexity if none is required. Yeah, well and excited.
Part of this all comes back to conflicts. You're not having conflicts? Yeah,
no, yah bother And the only time I've really run into situations like
that is if the function they give me is still way too tied to whatever
framework they're in. Yeah, then like, okay, then I'm just gonna
dit that one extra step of pure data in per data out versus it's all
other cruft that's going around there. But really you should be pushing that problem
back to them, going, guys, you need to invite a little here.
Yeah, and then they yell at you that it doesn't work, and
they're and their cat care business elsewhere, and you're like, it's free.
Exactly, give you money, pack, I'll give you all the money you
pay. So what's next in your world? Man, what's in your inbox?
Oh? Man, I'm like the past year or so, I've been
like Elbow deep and and modernization of ESPNT NBC to core Orp Corp. Done
at six, so a lot of like cloud migration, and let's also get
it off of asp net four eight and get it onto a net seven eight
whatever you know? And why six not seven? Because I started the project
a year ago before a relationship just that was it. I gotta enough to
do. I don't need to switch frameworks now. So I get to I
get to see like these projects are using my libraries. So I'm like,
oh, now I have to go through these migration processes because I have to
upgrade the code from you know, whatever I thought was a good idea.
You get to take advantage of the new features of C sharp too. I
mean one of the things I'm when I'm talking to folks who are coming out
of four eight now and looking at seven project, like your four versions of
C sharp behind, Like there's some good stuff you get by getting away from
four eight. Yeah. Step one, take everything out of startup, put
it in program and make and make what do they call those you know,
the controllers that are right there yeah, yeah, exactly without move all your
controllers into these anonymous yet school boys sex just copy and paste everybody. Yeah,
probably got an Owen start up change six point zero, seven point zero,
and you're done. It's fine, We're fine. You know. It's
one recurring theme on the run as side. We were talking about, Hey,
you know what's good, wait another version, because the migration tools get
better, the validators get better, like everything will get easier. If you
don't see an immediate need for this feature right now, there's really there's strong
incentive to wait a little longer too you really need it, because it will
only get easier over time. And so this codebase was started with my previous
company back in twenty ten or so. So it's like all the mistakes of
Jimmy past that Oh yeah, you you hate your past self, Like what
was that idiot think? Yeah? Yeah, So that's like it's all like
you know, in tier sort of stuff, which isn't bad, but like
I can see like, oh gosh, they still got the managers and the
repositories and all this stuff, and so it's it's hard to test. It's
all coupled and yeah, all the things that I realized we had fixed like
and subsequent to that project. But it's kind of a snapshot in time,
right what we thought was, Yeah, I mean it's good to be kind
to yourself. It's like that's what we thought at the time. We have
learned since then and now I have to clean that up. Hey, before
you go call back to the to the comment, do you get many contributors
in the sense of like financial things or anything for automapp or mediator, Like
does that happen? Oh? So, I mean I do have my geth
hub sponsor link on those projects, but the levels are basically tied to different
qualities of alcohol you could buy me, so like one hundred dollars a pretty
decent bottle of whiskey and that you know, you know down like craft beers
levels or just like pb PBR at the bottom PBR level. So, I
mean I have received one significant contribution. That is, uh, my project
or automapp or was recipient of the ADBs dot nets open source thing last year.
Thank you. I don't really know what the state of they where they
are now because they had a big contraction and their team so like, oh,
they did a few donations and then I think I don't know if they
just saw like dot and that's not a big deal for them or whatever,
but just the one. But I'm I don't expect that or seek it out
either, because no, no, I mean I always get the sense with
you, Gym ever talk to you, it's like you're just busy doing the
work for your customers. Yeah, and this other stuff comes out the side
of that, and that's nice, but it's not your focus. Yeah.
I just coming from a product background as well, I knew like I would
have to. I have to design for the people that are actually using it
that I could talk to and get feedback from. If I just design something
socially open source libraries like you put it out there, but how do you
how do you get that feedback from people using it? And so I can't,
you know, I can't sign an NDA with everyone that comes up and
says I have this problem. Okay, let's really dig in to see what's
going on there. It really I don't know. I don't want to do
the support thing either, So I just design for what's in front of me,
the people that are paying me to do work for them, and then
I will then I know that whatever I'm building will work for them because that's
what they're paying me to do. And if I just put out there and
other people can use it and they get value from it, that's just kind
of icing in the cake. But the primary focus for me is the people
that actually pay to have this work, that are paying you. I mean
that being said, you have had a few tributors to Mediator over the years.
I don't know that they're substantial. Oh yeah, code wise, of
course, no. No, yeah, for the code. Code is a
different thing because it's time and that's more more, more difficult. And usually
I mentioned they're solving their problem too by giving you a pull request. Yeah,
I just I mean it still it takes time for me to understand.
So what problem they're trying to solve, and is this the problem that should
be solved my library or is an actual issue whatever? Because there's half the
time the issues are raised. I'm like, it's not me, it's the
container. Go figure it out over there. There's nothing I did. I'm
not going to fix your broken container for you with peace software. That's not
how that works. Yeah, it's like it's just go and then make them
mad over there. That's fine, share the anger, Yeah, well,
Jimmy, thanks for sharing this with us. Mediator. Looks very cool and
I can think of at least two customers that are going to take a look
at it right now, So thank you, all right, thanks for having
me. I always happen to be on all right, We'll see you next
time 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 dt nt R o
c ks 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 you next time.
I got a treadmittal bands, Dolly and see the summer time is hard
than my tax