 Hi, and welcome to another episode of Visual Studio Toolbox. I'm your host, Dimitri Lailand, and today I've got a special guest, Jeremy. Jeremy, why don't you introduce yourself? Welcome to the show. Thanks. Hi. I'm here in nice and cool Atlanta actually. We had a front come through, so the temperatures drop feels a little bit like Redmond weather when it's good weather, not the regular rain. Not the hellscape that we have right now. Not the crazy stuff. Yeah, so I'm a client developer advocate with Microsoft. I've joined the team. I've worked with Microsoft in the capacity of an MVP and a consultant for about 10 years, and just recently joined the team a couple months ago, pretty excited and stoked about that. Awesome. Yeah. We're excited to have you. The mean you ran into each other, I think digitally before, I mean, I know your name's been around for quite a while, you've been part of the community, but there's this blog post that you did that triggered this episode. Why don't you kick off and tell people about your journey, the product you built, and why you wrote the blog post. I think that'll set the stage for why we're talking today. Sure. Absolutely. The story begins many years ago. In fact, the very first commit that I did to this particular tool was in 2010. I like to think I haven't been a big coder or fan of writing a solution just to try to find a cool solution. Most of the things that I write are solving problems. Right. The problem at the time was we had this great technology called Silverlight, and people were using it everywhere, but there wasn't a really good local database solution for that. Yeah. It wasn't a case where we were trying to build a full-fledged database. We know that we can use web service calls and connect to database front-ends, but even for simple things like caching, storing local data, it just wasn't there. When I went to look for solutions, most of the solutions required you to buy into the solution. What do I mean by that? If I was creating an app for food, for example, and I'm using that because I have a great food example, I might build classes that are food-related classes. Well, to use these tools, you had to actually inherit from their base classes or implement certain interfaces and go through a lot of changes to make it work with Silverlight. Out of pure frustration, I built a tool that my rule was very simple. I shouldn't have to change the classes that I already had in my application, but this tool should allow me to be able to define what is the unique key on the class, store the class, serialize it, bring it back in, have some indexing capabilities, and basically give me a local database capability with really low friction, really low onboarding. Yeah. It's a paradigm a lot of us were familiar with right back then. Silverlight needed that, I was a Silverlight developer back in the day, so I fully appreciate the need you were trying to solve, and that back and forth clean civilization without a lot of complexity is a must. I mean, it's still a must today in the most modern UWP app or whatever. So the problem is the same, but you had a very particular moment in time, you try to solve it, right? Yeah. I had a particular moment in time. At the time, we were following the MVVM, the Model View View Model pattern and needed ways to store sessions. So we used it a bit in Silverlight, but the irony, and I didn't see this coming, was that right around the corner was the release of Windows Phone. And when Windows Phone was released, it was released with Silverlight Support, and so it was a very easy pathway to take Sterling, which is what I named the database, and I'll tell you why in a second. Sure. But I took Sterling and ported it to the phone, and it was one of the first database solutions available locally on the phone. So that really drove adoption some early fitness trackers and some GPS systems, and a few pretty prominent apps picked up Sterling in the early days just because it was one of the first databases to get to market there. Yeah. But just a quick side story, the name was actually, I wasn't too super creative obviously at Silverlight, and this was Sterling, but I was always fascinated by the fact that there was this DLL in Silverlight, that was the core DLL. If you've done .NET programming, you know there's a core CLR in the base classes, and in Silverlight it was called AG Core. And it is so obvious now that I know why, but when I first saw that I was like, why would they call this egg core? What does this egg core mean? And then I realized, oh, the chemical abbreviation for Silver, AG. I actually didn't know that. That's news to me. Yeah, so it was the Silver core. So I said, I want to do something sneaky like that for my database. Ah, let's call it Sterling. Cool. So you created this product, right? This database technology, and like what .NET framework were you targeting at the time? I mean, this was Silverlight, right? I already, my mind's already fuzzy, like what was Silverlight's .NET version or how that even worked? Right, so when I first built it, it was definitely Silverlight 4, but around that time, I think, and this is actually important because it brings us to the present time too. There was a new type of library that was just becoming popular called Portable Class Library. So once we got to the phone, we realized we have a code base for Silverlight. Now we have a code base for the phone. You know, right around the corner was the whole Windows 8 launch and some of that technology. And so there needed to be this solution. So the Portable Class Library came out and what was 9th library is it covered enough API surface area that I was able to quickly take Sterling and build it as a Portable Class Library. So the way it was architected was all the core pieces that did the serialization and indexing and understood how to manipulate the database. That was all portable code back in the day, which is interesting. I'll talk a little bit about that in a second, but then the very specific items, for example, in Silverlight and the browser, we had isolated storage. In the phone, we had a special phone type of storage. Device specific considerations you always had to consider, right? PCL gave you that, that's your generic code, but there was always that extra thing you had to do. Right, exactly. PCL was, and a lot of people don't realize this, but PCL was sort of a clutch, right? It was an illusion. It created these type forwarding classes, but at the end of the day, there were two challenges with PCL that I think, you know, .NET standard addresses today, but the first challenge was that you had a lowest common denominator, right? So when you wanted to target platform X, Y, and Z, it was a minimum set of APIs that can be accommodated on these platforms. The second problem, though, is as more platforms came out, that matrix became so complex. It was like, if I check these three, what is the magic combination of APIs that are supported and became tough? So I kind of call that the framework down approach. It was like, here's the frameworks, let's take it down to what's common, whereas .NET standard is the standard out approach. It's let's implement a standard that has a core set of APIs and then build these other projects to adhere to that standard, which in my opinion is a much better approach. Yeah, I mean, PCL at the time solved the real problem, right? We needed to share code across all of these places where .NET was running at the time, the silver light, the WPFs of the world, the Windows phone, the Windows 8, I was developing all of those platforms. So PCL and me spent a lot of time, like you said, checkboxing, just enough to get it to work and then building the specific libraries wherever they were needed for something really device specific or platform specific. And you're right, it was that, I like the way you described it, I never thought about it that way, but it is the approach of really building to the lowest common denominator. I think today's world is very different than it's cool that we sort of got your project all the way to here. So why don't you tell us a little bit about like what was your blog post all about? Because it kind of takes that, you know, your database project, your PCL work, all of that and brings it to the modern era. So how did you get to today's point and what did you do? So it was interesting, it's a small world. At the time, I was not working for Microsoft, but Tim Heuer was very involved with Silverlight. And in 2011, I think it was, he tweeted a post and said, when is Jeremy gonna port Sterling? So I said, well, that sounds like a good challenge. Let me go see. So I cracked open.net core at the time, the 1.0 version. And let's go ahead and serialize something. Oh, wait, there's no binary writer. Okay, let's reflect on the class. Cause remember the whole rule for Sterling was that I wouldn't have to modify my classes. So I need reflection to look at them. Oh, wait, the full API surface area isn't there. So it was really a stopgap for me. And what's interesting is.net core, the first release addressed a lot of scenarios. And we used it actually quite a bit at my last consulting company for Greenfield projects. If we were building something fresh, we had the tooling there, but where I think a lot of frustration came from was from authors of tools and frameworks and libraries and even enterprises that had existing code who wanted to migrate their code. Well, they kept slapping into that barrier, right? Of the API doesn't exist. There's just not enough overlap. Yeah, that's always the number one fear I think we have as developers, right? It's even less about existing projects because often you don't touch those nearly as much as you'd like to. It's more about the community of projects that you know you depend on for the next project and can they get there with their libraries? Because we all depend on open source so much compared to the Silverlight days. Let's face it, it's even back then we were starting to more and more with project like yours. And today I can't imagine any real world project on Windows or .NET framework in general without support from various frameworks. So it sounds like you were part of that problem space. Yeah, it was definitely part of the problem space. And what is interesting at the time is the iteration that Sterling grew to. So it built support for the Windows runtime several because it was open source and this was before open source has been out for a long time but in the .NET community it wasn't as popular at the time but it was open source on coplex. So we had a lot of interested individuals on different projects contributing and solving problems and it was really neat for me as a developer to see that concept of someone doesn't just have to come in and say, hey there's an issue but they would literally post, here's an issue, here's a patch, you can fix that. So it was frustrating not to be able to bring it into this .NET core but quite frankly at the time it was brand new too and I'm not sure where the demand was so I sort of set it out there, said you know what for a lot of the mobile applications now there's other solutions, there's ports of SQLite, there's a lot of other tools that are available so I'm not gonna invest much time in it which brings us to now because the announcement of the release of .NET Core was coming up and I was very curious about what the story is, what the change is and so I started looking into .NET Core 2.0 and of course to do that you really have to understand the separation between .NET Core which is the implementation and .NET standard which is the interface and describes what that implementation needs to adhere to, right? So it becomes a minimal requirement so .NET Core adhering to .NET standard 2.0 says minimally it's gonna support all of the APIs in 2.0 so I said great, let's see what APIs are in 2.0 and I started digging and I don't have the exact figure but I think it's something like 13,000 APIs that were in 1.6, the previous .NET standard jumped to 32,000. Yeah, it's quite exponential of a change, right? It's a lot more APIs, they're bringing .NET really to the point where it's quite productive even for existing projects, right? And that's I think where you you started to look at it again. Yeah, I looked at it again and said, okay, you know, we've got XML serialization, we've got the binary readers and writers, reflection had thousands of new methods ported over so it really got me to the point that I said, I wonder how hard it will be to migrate Sterling because I keep hearing one of the challenges and stop gaps .NET Core great for new projects, what about migrating existing? I said, I've got this perfect project that I put on the shelf that uses reflection, uses serialization, uses a lot of advanced APIs in surface area, let's see what it takes. So I pulled down the project, literally built a new class library targeting .NET standard two and just dropped all the files into that project. So I use the .NET console, .NET new class and a classlib, which does the .NET standard, dropped them in, went to compile. The only compiler issue that I got was the resources I was using. So I was using a resx file and it was an old way of doing localization and that resource didn't compile to it. So I really quickly hacked it by making a static class and just surfacing hard-coded because this was for exceptions that were being thrown. So I quickly went through the list and just copied them from the resource file into the class, it compiled and it worked. I said, well, this can't be right. I mean, I was expecting more work than that. So let's write a little test tab. Yeah, let's write a little test app wiring some objects and query them out and lo and behold, it worked. And so I was stunned and in my mind, I've been in consulting for a lot of years and I've talked to a lot of people just in the past few years about .NET Core. And I think a lot of people were concerned about that API surface area. So in my mind, it wasn't really about Sterling that I wrote the post. It was about all the new capabilities for 2.0 and Sterling was a way to show how that's changed. That story changed from literally 2011, didn't even wanna touch it to here we are 2017 with just one small tweak I'm able to get compiled and ported. And I said, how many other libraries are like that? Well, there is a blog post that came out with the announcement for .NET Core 2.0 and by that team's estimate, they said in looking at Nougat and scanning the API surface area in Nougat, 70% of the projects should be API compatible with .NET standard. And so that's a lot of people that if they're not aware of this new capability are missing out on having their library available in a lot of different places, right? Because we've got Xamarin support for .NET standard, we have Mono, we've got the .NET Core, we've got the .NET framework. And in preview, I believe coming out, I don't know when is the Universal Windows platform support. They actually didn't ship that already. So I think that just came out very recently. But yeah, it's basically up to each ecosystem to get up to .NET standard 2.0 compatibility right with that specification. So it is a bit more work, but I really feel for the community of projects out there encoded, it really is the right way to do it. We can't always head down towards the minimum. We have to head towards something that people can actually build real solution towards. And I think it'd be cool to show people your converted project, is that something you can demo for us a little bit? Absolutely, I have a screen here that I'm going to share for you. And what I did is this project is out on GitHub. Let me just pull this up. Yep. I'm going to show the GitHub first. So it's Sterling.NET Core. And originally I had just done a very simple test that I'll show you, but I wanted to write a Meteor test to demo today. So I'm going to walk through what that looks like in a second. Let me pull up my Visual Studio Code. So basically in this project, you can see Sterling Core. So these are the bits of Sterling. We could spend hours going through the pieces. And I think it's a lot easier to demonstrate with how do I hook up into Sterling? So I'm just project including it. I haven't packaged it as a NuGet package or anything, but I'm just doing a local reference. But my test was literally I created a cat class that has a string key and a string name. I created a cool color class that has a GUID ID and a string name. And then I created a planet class that has an integer ID and a string name. Sterling actually supported triggers. So I went ahead and created a GUID trigger so that if I don't initialize that ID, it can initialize it for me and generate a new GUID for that. And then I've got this database definition. So the database definition does inherit from an instance, but you notice these classes have no attributes, no inheritance or anything. Yeah, it's very clear. They're pure. So there's this fluent interface that defines what is the key. So for cat, the key is a string, so it's C key. For cool color, it's a GUID. For planet, it's an integer. And then we've got this combo and the combo class aggregates has an ID and then it has a cool color planet and a cat. So one of the things that is unique about Sterling is it behaves sort of like a object document database, but it maintains referential integrity. So it's smart enough if I save one of these combo objects instead of serializing the full color, it's just gonna serialize the key and go look at the color serialization to deserialize that. So that was one of the features to reduce the footprint of the size. Because remember, this was phone days when we could just go out and buy 256 gigabyte, small cards that we could slip in there. So the database does this, we've got an initialization. I've just created colors, red, orange, yellow, blue, blah, blah, blah, Panther, Cougar, Lynx. These are just initializers. It's creating the objects, building up its own key for some of them. And this is literally it. It's just DB safe and that serializes it. Sterling has everything it needs to know to do that. And then in our main program, what this is doing is it's registering the database. And what I did with Sterling is I separated the driver that persists everything from the database logic itself. So that meant I could have an in-memory driver to have an in-memory database. I could write an isolated storage driver. I even had someone who wrote an Azure table storage. Oh, that's great. So there's, it's extensible in that way. So what this does is it populates the database and then it does a query and it does the queries a couple of ways. I'm just gonna run this really quickly. Let me pull this up and get into the right folder. So this is my little git batch shell. So if I go into Sterling console test, we're just gonna do a .NET build. I'll do a release build and let that spin out and target. And what you'll see is it's gonna pull in the Sterling core base and build that. So that's the Sterling core. And then it's gonna build the test app and then it's gonna complete. And then if I do a .NET and I actually, I'm just giving it the path to the application right now, Sterling console test. If I could type correctly. I only do this for a living. Yeah. So it's saving colors. I just put a thread sleeve. That's why I took that. It's got 441 combinations. It picks a random color. And then it's actually iterating through that combo box based on the colors. And that's what you're seeing come out. And then it just tells you the time to complete, which is really slow here. I think because I'm sharing on Skype, it runs a lot more quickly when I don't have the screen share running. Yeah. And of course the most amazing thing about what you're showing is that foundationally, once you got it to .NET standard 2.0, this now can run on Windows, can run on Linux, can run in UWP when that environment supports it anywhere where .NET standard is supported. You now have this cross platform database engine from a project that you built in Silverlight days just to give our audience a context on the time here. And that's a great context. In fact, the end of my blog post is literally pointing out that in 2011, I wrote this little app in the day 2017 for the first time I'm able to run it on a Linux machine without modification, without doing anything special. And that to me is huge. So I'm gonna start this running. Now this is a little bit more advanced example. So while it's running, I'm gonna go through the code. What this does is goes out to the publicly available USDA nutrition database. So those files are hosted on a site. I've got parsers in this import that read the text files in, parse them into actual full models. So that's what you're seeing here is like a food group. It is a pretty straightforward class. If I can get it to pull up here, actually, let me expand. So food group is just a code and description. But then we've got a nutrient. So a nutrient has two parts to it. It maps to a food ID. So think of protein, carbohydrate, fat content. And then it maps to a definition because there's a very standardized definition for these. So these are nested objects. Now I'm just gonna go and go to the food item. It has an ID, it belongs to a group. We can nest that group inside of it. It's got description, short description, list of weights. So that's if it's a cup dry, a cup cooked, whatever, and nutrients. So what is happening down here is we're actually reading those files in, parsing them into these classes and then storing them in the Sterling database so I can run a query in a second. And just to show you, again, we're just looking at straight C-sharp classes. And if I look at my USDA database, what I'm defining is I'm telling it, food group has a string key, nutrient definition has a nutrient key. Sterling also supports a concept of indexes. And this is why I tell people, Sterling's not intended to be a SQL server or a Cosmos DB replacement. It's meant to be a local lightweight cache. In fact, the most popular use case for Sterling was what's called tomb stoning in the phone days. And that was when you had new models for your application state and wanted an easy way to save it off when someone flipped applications. So that's the idea here. But what Sterling does with indexes is because everything's serialized and deserialized, with an index, it'll keep that index in memory. Which if you think about complex large objects and you have thousands of those, that's a huge memory footprint. If I'm just storing, for example, IDs and simple strings, then I can store a pretty good amount of those. So in this index, what I'm telling it to do, and I can even create my own keys on the fly. That's what's beautiful about it, because Sterling just calls my lambda expression to evaluate the key. So I'm telling it, store is an aggregate key, the food ID and the nutrient ID, but create an index on the amount in 100 grams. So it'll say there's this much protein in 100 grams, or there's this much water in 100 grams. And so what it's doing is in that index, it's keeping that in memory. So even though it doesn't have the full food items in memory, it has the index in memory. So you can very quickly get to the entity that you want, and then you can lazy load the full entity for that. Yeah, I mean, those are real world scenarios. In any sort of application, and I've had to tackle this multiple times, you will sometimes have to load a lot of data, and you want people to kind of, as they type to look up various values, and you just need a little bit of help with that. That doesn't come for free, especially when you get to hundreds of thousands of objects sometimes with data in them. So it's kind of cool that you're able to take, you know, all those investments you made. I mean, this is code you wrote again, like six, seven years ago, right? It's old code, but it's code that's well written for what it needed to do, and you just freaking converted it to that non-standard. I'm very impressed, and this thing is still going on us, but it looks like it's pulling down a lot of data. Yeah, it's a lot slower. I should have kicked it off sooner. Again, I think the Skype is slowing my system down, but we can loop back to it. But I wanted to show this part. This is my import strategy. So this literally takes a list of items, and you can see I'm using generics, and imports it by bulk saving it. Now, this is a little wonky. This is something I need to refactor, because before we had our awesome thread library with tasks, we used background workers. Oh my gosh, mean background worker go way back. Yeah, so I know there's some conversion between the two, but I just used what was there. So this is using a background worker to save the list, but what I love about being able to use generics, right, as C-sharp as a language, is I can have a strategy where even though I don't know ahead of time the type that I'm trying to save to my database, it's all based on generics. So I can pass in food item, food group, and the same save routine works, and it's just reporting percentage done. You can see we're getting close to the end here. But what blows my mind is that this code using generics, reflection, and everything else is the same code now that's gonna run on a Mac. And in this example, everything I'm showing here, this entire screen, this is Visual Studio Code. So Visual Studio Code will run on Mac, it'll run on Linux, and it's done at Core, which will run on all those target areas. So all of this experience is the same no matter where you go. So what I've done is I've loaded the collection. So now I'm doing a query. I just wanna run this real quick and then show you the code and then we'll pop back. So this query is listing in the serial category, foods by protein content. So vital wheat gluten comes out on top and then pasta whole wheat is down here. It's just doing the top 20. And then we do it again for carbohydrate content and then we do it again for fat content. So we can see, okay, what foods are high in protein or high in fat. The way that looks if we come back over to the program and I expand my terminal back is using a link query. So I'm literally coming here, querying my nutrient key and joining it to the full food item. Using my split key, remember I aggregated the key so I can actually, as part of my link query, say split that and just compare one side of it. So this time I'm just looking for protein, order descending, select the tuple and then I lazy load the food value. That's why you saw a little pause. So even though it figured out the whole list of items, only as I asked form did it deserialize that full food item from the deserialization. And this at the time and again, I stress there's a lot of different very optimized solutions now but at the time for very simple inobtrusive way to basically store some of your view models or some of your cash data and then be able to query it. This was what the magic of sterling was about at the time. That's awesome. I think this sends a really clear message. If I was a library developer out there, it's easy to hear some team at Microsoft give some percentage and say, oh, this percentage, that percentage of developers can now look at their libraries and convert to this thing. But you're one of those people. You had a real project. This wasn't conceived to demonstrate this was a good example that just happened to be there. And to me that's what made your blog post so authentic and I love authentic stuff. And there you go, you showed it running so definitely no smoke and mirrors. This was real code. You've converted. It's up on GitHub. People should definitely take a look. If you're starting a project today from the other side of the fence and you're a developer that's looking at .NET Core, what message would you give them with .NET Core 2 and .NET Standard 2 in general? Like I think this release is from my perspective very solid but I'd love to hear your thoughts on how far .NET has come as a general framework. I think it's come a long ways and there's certainly very specific scenarios that need very specific parts of the library and the full framework if you will that makes sense for that. But in general especially if you're starting to embrace this concept and I hate to use overloaded terms I know everyone's saying microservices today, right? But if you think about it let's not focus so much on the name and just the concept and that concept's been around a while. Let's focus on one thing and do that one thing. Well, test that one thing, pitch that one thing, share that one thing, right? It's a component as part of an application. If you're looking at components I believe developers will find 80, 90, maybe close to 100% of their surface area can be handled by something like .NET Core. And what's nice about it is with the current versions you can mix and match, right? So the .NET framework can reference .NET Standard. So I don't believe developers are losing anything if they take a core first approach and then if they need to build the bits in the full framework that they... But if they're writing small services, APIs, endpoints there's a lot of advantage to doing core first. The lessons learned from how many years, right? Of the full .NET framework. This was an opportunity even though the API surface area is the same for that team to build it from the ground up and there's been plenty of blog posts about benchmarking and performance that's pretty impressive what those capabilities are. So we've got that coupled with the fact that for free as a developer you now can create a library or a code base that will run on so many different platforms. And you never know when that little utility or library you write may become useful may take off someone else might need it. You may not think that your app is gonna end up on a tablet or a phone, right? But if it does someday this sort of buys it to you for free and the last thing I'll say that I think is important too is it's tough to be a developer today and not talk about the cloud. That's what I do day in and day out is the cloud but when I look at software today I don't worry as much about how cool the technology is or the language I'm worried about what does it take to get it from the concept to then deployment, right? Because that's cost of business how fast can you get it to market how much of that pipeline are you focused on innovating and doing what's important versus doing all this side stuff that has to be done on every project standing up a virtual machine configuring it and what's nice is today when we're recording this general availability of web app on Linux and container web app was announced it that announcement just came out. Yeah, just hit the books. What's that? Yeah, it just came out like today literally like as we were preparing to record this episode. Right, and I think programming aside and what does it take? Does it support generics, whatever? What is that pipeline for continuous integration and deployment and there's some very mature pipelines that can package.NET Core Apps into a container? There's tooling that's built in, developers I'm showing visual studio code developers don't have to leave the full visual studio to get this experience but what's nice is with tools like this I can take something like container web apps I can containerize my.NET application take.NET Core, right click, add Docker file create image, post it out and deploy that to an infrastructure that will automatically scale instances gives me a dial I want five I want 10 or based on CPU or based on request have all this auto-scaling capability without the overhead of me having to understand all the nuances of the infrastructure behind that and I think that's huge is that coupling with this technology and what we have available in the cloud for rapidly provisioning nodes and infrastructure to run the.NET Core Apps and that's what gets me excited about it. Yeah, it's really come a long way I think if I had any hesitation to tell somebody to go try.NET Core before I think 2.0 and standard 2.0 really has taken those away and I speak in an authentic way like you I come from consulting background I know how important it is for people to actually solve real problems and be productive and meet budgets and all of that I mean that's the real world people live in and we get to play with all this cool tech on the other side of it so when we give a suggestion we're asking people to spend their time and their money and I think for once we can do this with.NET Core 2.0 and be really confident they've got a great web story, UWP story, they've got componentization they can go to the cloud with it they can run it on Linux they can run it on Windows the sky's the limit to take some puns aside there but yeah it's awesome and it's really awesome that you came on to show this to us today I really appreciate it. Yeah, thank you it's I had no clue just like when I wrote Sterling it was to solve a specific problem I had no clue it would solve it and become popular the way it was back in the day but this blog post that I wrote I wrote because I was excited I saw what was possible I said I want to write about this and share it plus and you know this is kind of a guilty pleasure but to find a tweet that's six years old and finally be able to reply to it yeah that's awesome at the end of the day I replied when he said when are you gonna port I said how about now right yeah and linked to that was a lot of selfish fun but it went viral and a lot of people picked it up and I think it is because there is a desire to tap into the features and functionality and there was a little bit of reluctance based on the history and the track record not of issues but just lack of API surface area so I really do feel with .NET Standard 2 and .NET Core 2.0 that it's a major game changer and that people should take it seriously take a look at it and you know what I'm gonna put myself on the hook and on the line for this but go take a look at it try it out and if you have issues or problems with it reach out to me I'm very reachable my blog has contact information my GitHub does and because I'm interested in removing friction and helping make this happen I can't do it myself obviously but I'll bang on very transformative and I would love to see that 70% of new get packages that can support .NET Standard 2.0 .NET Standard I think that would be really awesome All right, well thank you Jeremy so much for coming on the show and we'll put the links to your GitHub repo the blog post and your Twitter handle so folks can actually reach out to you and bug you and ask some questions I'm sure people will have them and you know hope to have you on again and you have some more awesome stuff to show us Sounds cool Well I will do my best to work on awesome thanks again for having me on the show Thank you for being here and thank you for watching Visual Studio Toolbox Hope you come back again Take care folks