On this episode of Eat Sleep Code guest Jimmy Bogard shares his perspective on Microsoft's basic object-mapper. Jimmy talks about the future of Automapper and support for .NET Core & .NET Standard.
Jimmy is a member of the ASPInsiders group, the C# Insiders group, and received the "Microsoft Most Valuable Professional" (MVP) award for ASP.NET in 2009-2016. Jimmy is also the creator and maintainer of the popular OSS library AutoMapper. Jimmy is the chief architect at Headspring, a software consulting company headquartered in Austin, TX.
00:00 Ed Charbeneau: This podcast is part of the Telerik Developer Network. Telerik, by Progress.
00:16 EC: Hello, and welcome to Eat Sleep Code, the official Telerik podcast. I'm your host, Ed Charbeneau, and with me today is Jimmy Bogard. How you doing Jimmy?
00:25 EC: I'm doing great, doing great. And yourself?
00:27 EC: I'm doing excellent. We're just enduring some rainy, spring weather here in Kentucky. How are things in Texas?
00:35 Jimmy Bogard: Well, it rained, which is kinda rare for Austin. So that was good, I guess.
00:43 EC: The warm season's coming. I feel bad for you. I used to live in Florida and I'm not a fan of the heat, so I know what's coming your way.
00:49 JB: Oh, gosh. The warm season is the year.
00:54 EC: It never stops, right?
00:55 JB: No.
00:57 EC: So I wanted to get you on the show today, because of a GitHub issue I saw on the MVC GitHub repository. And this GitHub issue is... It reads, "Basic object mapper for simple model view. View model property mapping." And I have a feeling that you have some opinions about this, having one of... A very popular NuGet package for '.NET' AutoMapper. And it's been quite successful. And this, to me, it looks like it may step on your toes a little bit. So I wanted to get you to talk about kinda where you're at and how this affects you. But before we get started, why don't you give everybody a quick introduction of who you are and what you do, Jimmy?
01:56 JB: Okay. I guess I really write code for customers for a living. I work at a consulting company called Headspring out of Austin, Texas. And nearly all of the open-source stuff I work on, is just stuff that I build to help my clients. It's just tools I wanted to keep using, and using, and using as we go from client to client. And so, almost everything that I write and use these days with open-source is stuff I'm actually using on client projects, that I don't wanna lose when I go to the next client.
02:33 EC: And you have this tool called AutoMapper, which is an object mapping tool. Why don't we give everybody a quick elevator pitch. What is an object mapper?
02:46 JB: Well, the basic idea is I have two objects that look pretty similar, and my general use case was I'm building web applications in ASP.NET MVC, typically. And I have a rich domain model that's bound to the database in some way or another, usually with an ORM, like in Entity Framework. But then, I had this other thing I'm using to show information on the web, either for showing forms, or also posting data from the web. And you have this general problem, and that's your backend object is generally very rich and behavioral, and has a lot of things associated with it, but the thing you're coming in from the web, is generally not. And you typically don't wanna mix those two things together. So about... Gosh, eight or nine years ago, I saw this issue of when we're starting out MVC, that we wanted to have these DTOs that we use for the MVC side and have these rich backend objects. But what would be the mechanism that we copy that information from the rich backend objects to the frontend dumb DTO objects? And I didn't wanna do that all by hand, and I looked around, and saw there really wasn't anything that did it for you automatically. And so, I created AutoMapper as a way to automatically figure out how to copy information from one object to the other.
04:12 JB: Probably a stupid idea. That didn't seem that complicated, but there were a few things that I wanted to have out of the box that would help us out. One of the big ones was flattening, so if you have "foo.bar.baz" on your destination object, you could just have a single property, "foo, bar, baz." And it would automatically traverse those associations, and figure out how to flatten that object for you. It handled nulls as well. If foo was null or bar was null, it'd be able to handle that as well. And the other big thing that I wanted to do, was make sure we could test it as well. So if I misspelled something or removed a property, I could just have one line of... Just check all my configuration is valid, and all the names match up, and there's nothing missing. And if there is, go in exception, so it's really easy for us to test, to say, "Make sure all my mappings are good."
05:04 EC: Yeah, I've actually used this quite extensively and the testing helper worked really good. You can just check really quickly, "Do these two models align?" And it gives you fast feedback, "No, they don't. Go fix it."
05:20 JB: Yup. [chuckle]
05:20 EC: And it's very helpful, so you don't end up finding those errors deep in the development cycle, especially if you're making changes with things. You rename an object or something, it'll pick up on that and catch it.
05:34 JB: Yeah, you just catch it right away. Now, if you hand-rolled these mappings, of course, you'd find it right away, because you'd get a compile error, but again, those are just... The project that came... When I came up with this library and we were looking at thousand, and thousands, and thousands of lines of code and mapping, we're like, just no way we would wanna write that all by hand, and have to support it, maintain it, and test it. So that was the general ideas, that we're about to write a whole bunch of mapping code by hand and I just didn't want to. [chuckle] I just didn't wanna do it.
06:04 EC: Yeah, so let's use that, I guess, to get into this subject with what's going on with Microsoft. They have this GitHub issue out and they want to build a simplified version, I guess, of an object mapper that comes out of the box. I was on the previous podcast... We do a news summary podcast every other week... And I talked about this already a little bit, and I said, "We see this happen a lot with Microsoft, where they have a framework or a system and they decide to add features to it that already exist in either the community or commercial software, and they end up either killing off something, or angering the community."
06:52 EC: How does this affect you? They're basically proposing that they build a version of... It may not be the same feature-complete level as AutoMapper, but they're implying they wanna build the same thing.
07:06 JB: Yeah. Taking a look from Microsoft's perspective, and just what they've had available to solve this interval problem, and the overall problem that you have, is you're trying to bind raw form POST data to some object model that you can then do something with. And so, typically, what you see from a lot of examples online, from MVC, are using your rich backend data model, your domain model, whatever you wanna call it, the thing that's bound directly to the database, using that as the object that you use to bind form variables from. Now, there's a big problem with their security issue, that's gonna be mass-assignment security hold, security... Whatever. So that you accidentally allow a lot more form variables to be posted to your object model than you originally intended to. There are a few ways around this. One is some out-of-the-box features from MVC that you can use a little bind attribute on your form POST action parameter to explicitly allow or disallow specific properties. And that is achieved through a very maintainable string of comma-separated property names in a string. The other way... [chuckle] Of course, that's impossible to maintain and easy to screw up.
08:34 JB: And the other thing that people often do, is create a very specific DTO that just represents the information on the screen, and then, that is, effectively, your allowed list of properties to bind to. And then, from there, you take that list of properties, and then, associate that with your backend data, your ORM models, or whatever you wanna bind that information to in the backend. So with this DTO, it allows you to have a very specific form object, but there is zero out-of-the-box tools from ASP.NET MVC to facilitate doing this kind of development. They already provide this bind attribute to either allow or disallow certain properties, but there's zero to have this kind of DTO-based development. From their perspective, it's just a, "We want to solve the mass-assignment security vulnerability that everyone has to deal with, that does any sort of web development." And it's not specific to ASP.NET MVC. This is a really big security hole and Ruby on Rails a few years back...
09:42 EC: Absolutely.
09:42 JB: And they had a similar sort of solution, which was, "Here's an allowed list of things they want you to bind to." In the '.NET' world, because we can build these DTOs pretty easily, then our team solved this eight or nine years ago, by just building these specific DTOs. This is something that...
10:00 EC: Those whitelists in Ruby were kind of a pain.
10:04 JB: Yeah, kinda.
10:05 EC: They were a pain to maintain those things.
10:08 EC: Also, why do we need this? Why don't we just go right from Entity Framework to the view? [chuckle]
10:17 JB: Well, that's it, that's the... It's a problem. There's a whole host of other issues that you run into, if you just take this Entity Framework or NHibernate, whatever, thing and just shove it in the view, because that's typically when your DBA starts screaming, because you're like, "Oh, yeah."
10:34 JB: You have these database problems, because... I iterated over a collection in a table, and now, it's making all these queries in the backend. For a whole host of reasons, we, many years ago, wanted to go the DTO route, specifically creating 'individual view models,' as we call them, for every single form we show on the page, or even, every read-only view, as well.
10:58 EC: So from Microsoft's standpoint, they're trying to alleviate this problem from the end user, but hasn't you and the rest of the community solved this?
11:12 JB: I think so. From my perspective, it's a bit of a solved problem from my end. But I can... I do always try to see the other side on this. And the other side is they want to just have something... Their initial intent was just to have something that solved the mass-assignment vulnerability problem. Now, AutoMapper is a very rich tool that does a whole lot of things. And it's also quite opinionated, in that it's my opinion about how to build MVC applications. And so that kinda runs contrary to Microsoft's perspective. They don't really want to provide a lot of opinions on how to build things out of the box, but they do, would like to provide something that's small and lightweight.
12:00 JB: I was contacted by the team before, really, many of anyone else saw it. And my general feedback was, "Great! This is a... " I've been struggling for years to try to teach people how to build MVC applications differently, and better, in my opinion, so you don't run into these issues of mass-assignment vulnerabilities. You don't pass a lazily-loaded, enabled in Entity Framework thing to the view, and now, I have all these crazy queries going on and all sort of crazy stuff. From my perspective, it was a, "Great! Let's help people build applications better." And if there are things that are missing from AutoMapper, that precluded you from using it, then I wanted to understand what those were. It's a tool that I've used for years, and years, and years, so I know it inside and out. But if one of the reasons why it wasn't being looked at, is that it didn't have a sufficiently low bar for entry, then that's something, I said, "Okay, tell me what you're looking at, what features you're looking at, and then, I will do my best to make sure that I can have it also low bar on my side, as well."
13:15 JB: Initially, my perspective wasn't, "Hey, you guys should use AutoMapper." It was more, "Hey, what are you building, so that I can copy it and make sure that it's really easy to transition from whatever you built, whatever I build?" 'Cause what they were looking at was, literally, 100 lines of code, of just things with the same property names, copy them, and call it a day, and not looking at things like flattening conversions, all the crazy things that I support in AutoMapper. They weren't looking at that. They would say, "Okay, if you want anything more, go use that." So from my perspective, I was looking at, "What would be the easiest way I can have to get people to transition from one to the other?" But I guess it got out, and [chuckle] I was actually away for the weekend, and then I came back. My Twitter reply box was just ginormous.
14:13 JB: And then, I guess, a lot of other people were upset about this. I wasn't. I wasn't really... I just, yup... I want people to build applications well. And I really just wanted to understand what was stopping you from using, from just including in there, and we'll see if we can fix that. But if we can't, "How could I make it super easy?" But I guess other people had their opinion and wanted to just say, "Use AutoMapper." And I thought, "You know what? Actually, what would that look like, exactly?" So this point, for... Gosh, that issue was like 100 comments, 200 comments. I couldn't even keep track of it. We're just trying to figure out, "What would that look like, if it would have been included?"
14:58 EC: Yeah, 'cause we've done something similar in the space with Newtonsoft, the Json serialized, de-serialized stuff. So would it be a similar situation where they just default to AutoMapper for the object mapping? Is that kind of what's been put on the table as an option?
15:27 JB: Yeah, there's a few options on the table. One, obviously, is to just use AutoMapper. So we will include that in the file, 'New Project Template,' for certain templates. That's one option. Another option is to just include a very dumb version of this. So basically, what they're looking at was, "Take those 100 lines of code and include that as a package." That'd be another option. Another option would be to do neither. Just say, "Object mapping is a thing you should do." And then, in their docs, which are on docs.asp.net or something like that. In there, in the documentation, say, "Okay, when you're building an MVC application, you should really use these DTOs. And here are some tools to make that easier for you." So instead of them, more or less, blessing a single library. Then they can say, "Here are some options that you have available for you." Personally, I think it's similar to the Newtonsoft, the Json.NET situation, but it's different a couple ways.
16:39 JB: One, it's very difficult today to build an MVC application that doesn't have Json serialization at all. It's one of the core things that's part of MVC and web APIs, is the ability to take Json and serialize it to objects. But the argument isn't so strong for an object mapper, so there are quite a few comments on the issue that said, "Hey, I never use AutoMapper. I don't want you cluttering up my file, 'New Project.' Why do we have one more thing we have to reference?" But for people like myself, it's basically, every single project I use it on. So you can see, "Well, how do they balance trying to make things lean versus recognizing what's going on out there?"
17:25 JB: Then, there's the issue of just Microsoft blessing a specific library and saying, "This is the one that shall win." Now, from my perspective, I don't... No matter which way it goes, AutoMapper is a pretty established library out there. I'm not really concerned about something consuming it. I know a lot of people that do open-source that are really concerned about it. But for something like my stuff... I'm not... My libraries don't make me money. I don't charge for support or anything like that. It's purely just things I build for my clients and I mainly just try to make my clients happy. And if other people are happy with the stuff I build, that's great. But I'm mostly concerned about my personal clients. But it does set a little bit of a precedent that says, "Okay, if they create this open-source library... " Microsoft doesn't have a great track record, historically, of just adopting other people's open-source stuff. You can look at dependency injection containers or even MVC itself. When MVC first came out, people are like, "Why can't you just use Castle MonoRail?"
18:40 JB: Which was a thing many years ago, but now, it really isn't a thing. Or MStest.
18:45 EC: Entity Framework.
18:46 JB: Entity Framework, yeah. There's a long list of things that people can point to and say, "Microsoft just created their own version of the thing that really wasn't any better, as opposed to investing in the existing open-source tooling that was out there." One of the historical reasons why Microsoft did that in the past, but pretty much got away... But then, you see something like this, and that's why people get pretty sensitive about it is, "Gosh, this is just Microsoft up to their old tricks." [chuckle] I've actually read every single freaking comment on the GitHub issue.
19:18 JB: And it honestly seems like no matter what Microsoft chooses to do, there is someone in that issue list that has a problem with it. I think if they... I don't know what they could do.
19:25 EC: Yeah. [chuckle] You're not gonna make everybody happy, that's for sure.
19:29 JB: No, no. There's actually people who are pretty extreme about it. It seems like no matter what choice they make, they are destroying open-source, based on the comments I saw there. So if they include something, they're destroying open-source. If they decide to use AutoMapper, they're destroying open-source, because they're promoting one library over another. If they just include it in the documentation, they are, again, destroying... It's just... I really feel for them, but I don't envy them. [chuckle]
19:54 EC: Yeah, for sure. It's like the presidential elections all over again. [chuckle]
20:00 JB: Yeah, I just... Yeah.
20:01 EC: It's like two angry sides and nobody wins. [chuckle]
20:07 JB: No, I think what's probably gonna happen here is... This issue garnered enough attention that I... I know they were... Just from a timing perspective, it's really easy to get in 100 lines of code into the next release of ASP.NET Core, so I probably... The thing's gonna happen is we won't see anything on this for this upcoming release of ASP.NET Core, but it'll be something they can look at the one after that as something to look a bit more deeply at, seeing how much people cared about it. 'Cause the top comment there is, "Why not use AutoMapper?" And it has 40... [chuckle] Oh! It has 52 thumbs up, whereas, the original issue has 52 thumbs down.
20:56 JB: It seems like a lot of people care about it quite deeply, so anything that has that much passion around it, I think they're gonna probably pump the brakes a little bit, and look a little bit more deeply, to be able to consider all aspects of this.
21:11 EC: Yeah, hopefully they do. And hopefully, if they do decide to implement something, it's very lightweight, and it doesn't feature-creep, which they've had a tendency to do with some of these other solutions, like Entity Frameworks, a big one I can think of. That's kind of... There were a lot of different projects out there that did the same thing, and it killed off, not only open-source projects, but commercial ones, and...
21:42 JB: This is from just a personal perspective. I can't see anything they do killing AutoMapper, just because it's so established. It's been around for such a very long time. And although there are other mapping libraries out there, there aren't really, I would say, any really competitive alternatives. I don't mean to toot my own horn or anything like that, but most of 'em are just copies to be slightly faster versions. I haven't seen anything yet that's a really different thing. One of the things I looked with coming out of it, is even if Microsoft were to just choose AutoMapper, like, "This is what we're gonna go with," then I could see that as a positive for open-source, because it would tend to consolidate just the normal features that you would see in an object mapper. And then, new libraries would pop up that have truly alternative things that they do. And one idea that people come up with, to me is, "Why can't you use Roslyn as the thing that you use to generate the mapping code?" Roslyn, being the Microsoft C# compiler. I thought that was a fantastic idea, because you could get rich stack traces of exactly what went wrong. You can have highly-performing... As good as hand-rolled code performance.
23:12 JB: But I wouldn't do it, simply because I support a wide array of platforms that are a much larger superset than just Roslyn supports today. If I went down the Roslyn path, I would have to have a much narrower set of platforms I could support, and that's not something I'm willing to take on, in terms of supporting two different, completely separate mapping internal engines, or just kill off a bunch of platforms I support. So this could be something, if Microsoft picks a single one, that could force actual innovation from other libraries, as opposed to being, more or less, the same thing.
23:58 EC: Now, let's talk about where the open-source project, AutoMapper's going. '.NET Core' is still fairly new. Have you been able to port AutoMapper over to work on '.NET Core?' And what was that process like for you?
24:19 JB: Oh gosh, [chuckle] "audible sigh" is probably the best response I can have for that one.
24:30 JB: I've had a long history in AutoMapper of trying to support other '.NET' platforms. I even had a Silverlight 3 release of AutoMapper way back in the day. So from my perspective, '.NET Core' was a big step forward in me being able to support a lot more platforms, including '.NET Core' itself. With their even latest tooling in Visual Studio 2017, it's really easy to make a library that can target multiple platforms. When I went to '.NET Core,' it was... If anyone's been paying attention to the '.NET Core' stuff in the past three years or so, you've probably seen a lot of churn in the tooling. Well, I've felt a lot of that churn, because I've had to change my projects, and my builds, and the packaging, and deployments to be able to support all the different tooling that's come out.
25:28 JB: Absent of all that, it's been fairly straightforward for me to actually port that code itself to support '.NET Core.' And then, one of the big reasons, is because Microsoft has moved from a cross-platform targeting approach for a code of Portable Class Libraries, which was a big hack, I think, but it worked. It was just very difficult to support as an open-source maintainer. To this new idea of defining a standard library of API surface area, and that's what's known as the '.NET Standard. Now, if I wanna support any new platform that comes up, as long as that platform can target a '.NET Standard' version that I'm targeting, I did just get it for free, and '.NET Core' is one of them. So is Xamarin. I think you can actually run AutoMapper on an Apple Watch, as well, because it's part of the '.NET Standard' that I'm targeting. The only one I dropped support of is Windows Phone Silverlight.
26:40 JB: So the four of you out there that still have a Windows Phone 8 Silverlight version, I'm sorry, you can't run, at least, this version of AutoMapper, maybe an older version. It's almost trivial now for me to support something like '.NET Core,' because it's just part of targeting the '.NET Standard,' and I get '.NET Core' for free, based on that.
27:05 EC: Now that we're through the churn of csproj versus the Json-based...
27:13 EC: 'Project.json,' and all that iterating over these different ideas, things are pretty good then?
27:21 JB: Yeah, for me, it's been greatly simplified, because of the focus on building command line interfaces through the '.NET COI.' My build process has gotten much more simplified over the years. It's funny, actually, in prep for this podcast, I went back and looked to see when the very first commit of AutoMapper was, and it was actually back in 2008, that the very first commit was. And [chuckle] the very first commit was almost all build artifacts of '.NET'...
27:57 JB: And all this junk to do all that. So like, "Oh, gosh. It was so... " Having assemblies checked-in directly, because there was no NuGet back then. It's like, "Oh, gosh. It's so much simpler now." From that perspective, the tooling has got quite a bit easier on my side just to be able to support and maintain. It's like, I gotta tell you, the last thing I care about these days is build scripts. That's just at the very bottom of my list of things I want to spend my time on.
28:26 EC: Yeah, solving the user's problems and the business problems is what we're here to do, and not write build scripts, and worry about source control, and hopefully, we have a DevOps person to handle [chuckle] some of the other stuff for us.
28:42 JB: Yeah. [chuckle]
28:45 EC: So Jimmy, do you have any events coming up? Are you gonna be anywhere giving sessions and talking about AutoMapper, or anything else?
28:55 JB: You know, that's funny. I've actually never given a talk on AutoMapper.
29:00 EC: Really?
29:00 JB: Like ever, maybe because I'm just using it all the time. It's just... [chuckle] It seems like a boring topic for myself. It's like, "Yeah, maps and code, there you go. Done. Mapper.Map."
29:15 JB: I do talk a lot about how we build applications. And so that's what almost all my talks are about, is experience reports of, "Here's something I ran into," or, "Here's looking back at a project over the last two years and here are the things we found out of it." I do actually have a few events coming up. And probably, the biggest one coming up for me, is NDC Oslo in June. I will be talking about building compositional user interfaces over microservices. Actually, using some of the tools that Telerik provides as well.
29:50 EC: Oh, excellent.
29:52 JB: Showing how that very last step of building microservices is, "Okay, now, I need a... The users want an app to consume all these things." And now, I'm back in Monolith hell, except with 100 times more latency, 'cause everything's an API call. That's the big one I have coming up and that's probably the only one I can remember right now.
30:18 EC: Just for full disclosure too, I had no clue that you're talking about that, so that's awesome.
30:24 JB: Well, it was the one that got accepted.
30:28 EC: Yeah. What about Code PaLOUsa? Did you...
30:31 JB: Oh, yeah. That's the two weeks before, I believe, Code PaLOUsa, and I don't remember what I'm talking about there. I probably should have this written down somewhere.
30:40 EC: Yeah, I will be there as well. I'll be talking about just a broad overview of '.NET Core,' and what to expect if you're an MVC 4/5 Developer, and you're getting ready to transition over into '.NET Core.' What are all the changes and what do you need to know? So we will both be at that event in Louisville and I will make sure to put some links up on our show notes page. So if you're in those areas, if you're in Oslo, or if you're in Louisville, you can come out and see Jimmy, and we'll have to connect on another show about something other than AutoMapper while we're both in town.
31:23 JB: Great!
31:26 EC: So Jimmy, where can we find your blog, and follow you on Twitter, and all that good stuff?
31:31 JB: Well, I'll try to make it easy. My blog is at jimmybogard.com and you can find me on Twitter at '@jbogard.' Twitter still uses the '@' symbol for some things these days, I guess, not replies anymore. And yeah, those are the two best places.
31:48 EC: Excellent. And you can find more links from the show on developer.telerik.com. And also, join us on May 9th; we're doing a Kendo UI webinar and we're gonna give away five Ultimate Angular online courses. That's the Angular Courses by Todd Motto, a very prolific Angular guy out there. He has some awesome courses that teach you everything you need to know about Angular. We got five licenses to give away for that and an Xbox One S. So again, developer.telerik.com, look for the links in the show notes for the Kendo UI Webinar on May 9th. Jimmy, it's been excellent talking to you again. Keep up the good work on AutoMapper. It's something that I've used in the past many, many times. And I'll probably, again, use on my next big application, whenever I get back into building some big full-skill stuff again. Thanks for coming on the show, man. I appreciate it.
32:51 JB: Thanks a lot, Ed. I appreciate it too. Thanks for having me.