<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Josh</title>
    <description>The latest articles on DEV Community by Josh (@sohjsolwin).</description>
    <link>https://dev.to/sohjsolwin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F159330%2Ffd5be0d8-3f07-41f4-a5dc-00c0d1757997.jpg</url>
      <title>DEV Community: Josh</title>
      <link>https://dev.to/sohjsolwin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sohjsolwin"/>
    <language>en</language>
    <item>
      <title>Engineer's Week 2020</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Fri, 21 Feb 2020 19:51:26 +0000</pubDate>
      <link>https://dev.to/dealeron/engineer-s-week-2020-21ii</link>
      <guid>https://dev.to/dealeron/engineer-s-week-2020-21ii</guid>
      <description>&lt;p&gt;This week (Feb 16-22) is Engineer's week. Similar to other themed weeks throughout the year, this one is focused on appreciating the engineers that work to build, support, or produce the things around you, as well as to inspire the next generation with engineering topics. &lt;/p&gt;

&lt;p&gt;Side note: &lt;a href="http://www.discovere.org/our-programs/engineers-week"&gt;DiscoverE&lt;/a&gt; is a great resource for activities and documents you can use to help engage with your local community for introducing people to engineering concepts in a fun and educational way. &lt;/p&gt;

&lt;p&gt;As this Engineer's week comes to an end, we here at DealerOn wanted to take a moment to thank all of our engineers that work hard every day to build and support all of the myriad systems behind our services and products. Thank you all for what you do; for sticking it out until the early morning hours when there's a large migration or system deployment; for reviewing and double checking each other's work to minimize any production issues; for QAing the upcoming builds thoroughly and catching any oversights or missed requirements before they get too far in the pipeline; for considering the user experience and use cases so expertly when designing a new interface for our colleagues or customers.&lt;/p&gt;

&lt;p&gt;From all of us here at DealerOn, Thank You.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Foundational Pillars of Successful Development: Community</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Fri, 10 Jan 2020 19:34:40 +0000</pubDate>
      <link>https://dev.to/dealeron/the-foundational-pillars-of-successful-development-community-3g8e</link>
      <guid>https://dev.to/dealeron/the-foundational-pillars-of-successful-development-community-3g8e</guid>
      <description>&lt;p&gt;In this series, I will focus on what I view are some of the necessary, foundational pillars of software development that result in better code and better experiences. First up, is Community. &lt;/p&gt;




&lt;p&gt;There are many components of successful development, and there's no end of arguments on which is the keystone holding it all together. &lt;br&gt;
Architecture and Style are undoubtedly important components of development, but I feel that Community is what keeps a developer moving forward when they've been staring at a wall of curly braces and semi colons for hours trying to figure out why their code is not compiling.&lt;/p&gt;

&lt;h1&gt;
  
  
  Making Friends
&lt;/h1&gt;

&lt;p&gt;Lets be honest, most people in the software development field are socially awkward. We gravitate towards this career path because it means less talking to the public and more zoning in to solve a problem. It's a great thing getting into the &lt;a href="https://efficientsoftwaremethodology.wordpress.com/esdm-home/what-is-flow/"&gt;Flow&lt;/a&gt; of things, and some of us can spend hours or (unhealthily) days in this state. We remember to eat or drink from time to time, and if we're lucky, we have someone that cares about us pop in every now and then to remind us not to die. &lt;/p&gt;

&lt;p&gt;Even though we typically don't enjoy frequent interaction with other "people", we don't always hold that same aversion towards our Cohorts in Code. They get us, they understand us, and we can speak with them on a level that the general public would just scoff at while exclaiming "Nerds...". These Brothers in Brackets and Sisters in Semicolons are our people, and having yourself a nice group of people to call your own can really boost your productivity and overall enjoyment of the development career path. &lt;/p&gt;

&lt;h1&gt;
  
  
  Branching Out
&lt;/h1&gt;

&lt;p&gt;Having local groups of people to call your own is certainly nice, but you really start building those social synapses when you find communities online that share an interest in your technology de jour, be that a specific language, framework, or coding style (Tabs vs Spaces, Fight Fight Fight!). Finding a local community is a good way to meet new people and build up that local group of your people, but it's also a great way to grow your knowledge. Many local meetups are looking for speakers, and no matter what level you know about a specific subject, there's always someone that knows less than you and would be interested in learning what you know. Everyone has something to teach.&lt;/p&gt;

&lt;p&gt;Personally, I learn best when I'm attempting to teach someone. Often if I'm going to be giving an introductory talk or lesson on a framework or topic, I'm barely one step ahead of the group I'm teaching. It helps keep the information fresh, and it gives me motivation to have it sink in and really understand it. That way, I can help the people I'm teaching get past the confusing and annoying parts that I just learned, without breaking their spirits by subjecting them to the 3 hours of "&lt;em&gt;WHY WON'T THIS BUILD&lt;/em&gt;" that I just sacrificed to the code gods. &lt;/p&gt;

&lt;h1&gt;
  
  
  Making an Impact
&lt;/h1&gt;

&lt;p&gt;Participating in online communities that cater to your technology interests isn't just about learning new things and meeting new people. It's also about encouraging and being encouraged. It's particularly beneficial for getting help on a particularly stressful bug or getting encouragement that your design decisions are valid and functional and not just the ravings of a caffeine-fueled,  3 AM, byte binge. On the other side of that coin, &lt;em&gt;you&lt;/em&gt; can be the voice of encouragement for others that may be in the same position you once were when you were getting started, or maybe you've already encountered that specific bug and know exactly how to solve it. Sharing information, knowledge, and support is a key component of what makes communities, friendships, and just life in general work so much better. &lt;/p&gt;

&lt;h1&gt;
  
  
  Get Out There
&lt;/h1&gt;

&lt;p&gt;Communities are extremely important for successful software development, as we rely on each other for myriad things to help get us through those days where we're bashing our heads into the keyboards in frustration. I'm not saying that you can't be successful in a software development career without embracing the communities around you, but you &lt;em&gt;will&lt;/em&gt; have a tremendously more difficult time. There are those rare individuals that will sit down at the keyboard, black out for a few hours, and come to as their build finishes on a glorious masterpiece. Most of us aren't like that, and, in my experience, most of us wouldn't want to be. That kind of solitary development often ends up in &lt;em&gt;extremely&lt;/em&gt; opinionated code and the person behind it usually ends up being kind of a jerk. Communities and friends help us to become better people, and in the process, better developers. &lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Developing Appreciation</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Mon, 02 Dec 2019 15:10:33 +0000</pubDate>
      <link>https://dev.to/dealeron/developing-appreciation-5hbm</link>
      <guid>https://dev.to/dealeron/developing-appreciation-5hbm</guid>
      <description>&lt;h1&gt;
  
  
  Thank you
&lt;/h1&gt;

&lt;p&gt;In this time of thanks and reflection, it's always good to let people know what they mean to you and how they've improved your life. This post is going to be one of my shorter ones, but I just wanted to take a minute to thank the people and teammates that have made this year a good one. &lt;/p&gt;

&lt;p&gt;First, I have to thank my manager and the entire management team at DealerOn. I can be a bit eccentric and tend to push back on tasks and things that, being the person closest to the work being done, don't make sense to me from a strategic, logistic, or technical debt perspective. At past companies, that behavior was frowned upon and actively discouraged. It wasn't about producing the best work we could, it was just about getting it out on time. Here, my manager and crew respect my drive to do it right and will listen to my reasons if I push back on something. It's not an immediate &lt;em&gt;"just get it done"&lt;/em&gt; shutdown, it's a discussion, and that makes me immensely grateful to be working with and for people that will step away from the hard business line from time to time and look at what's best for the road and destination we're traveling towards. &lt;/p&gt;

&lt;p&gt;Second, I need to thank my teammates. You guys keep me honest. It's great to work with people that take time to learn the whats and whys of the work we're doing, and it's great to have people that will push back against &lt;em&gt;my&lt;/em&gt; ideas when they disagree. I don't expect that I have the best idea every time, so having people that aren't afraid to say &lt;em&gt;"well, I think it should be this way, and here's why"&lt;/em&gt; is paramount for producing the best work we can from our team. You all are talented, motivated, and determined to raise the bar every day, and you do. &lt;/p&gt;

&lt;p&gt;Third, I want to thank my cow-workers (inside joke, puns for days). All of you make coming to work day after day so much more enjoyable. There's an eclectic variety of personalities, interests, experiences, and expressions of life that fill this workspace with so much energy. You all are what makes this a place worth coming to, and one of the reasons I love coming into the office even if I could work from home. &lt;/p&gt;

&lt;p&gt;So, I just want to say thank you to everyone. You help make my days better and I hope I in some way provide the same for you. You help me grow, keep me honest, and provide a worthwhile environment for me to feel like the best me. Thank you.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The year of the many hats</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Fri, 18 Oct 2019 20:38:42 +0000</pubDate>
      <link>https://dev.to/dealeron/the-year-of-the-many-hats-2p3d</link>
      <guid>https://dev.to/dealeron/the-year-of-the-many-hats-2p3d</guid>
      <description>&lt;h2&gt;
  
  
  Fifty-Two.
&lt;/h2&gt;

&lt;p&gt;That's how many articles DealerOn has published in the last 12 months. One article every week. When this project started, DealerOn had been wanting to get more involved in the tech community and provide some of their thoughts and insight on the various technical problems and challenges they've faced, along with giving everyone involved a few more excuses to learn something new and share that knowledge. At the core, the DealerOn blog arose out of a desire to grow, not only our public footprint and roots in the tech community, but ourselves as well. I've learned a great many things in this past year and my career has changed shape substantially beyond the "Engineer" role (hat number 1) as part of this growth. &lt;/p&gt;

&lt;p&gt;One year ago this week, our first article was published, "&lt;a href="https://dev.to/dealeron/why-car-lovers-make-great-software-engineers-2k2d"&gt;Why car lovers make great software engineers&lt;/a&gt;" by our very own Tim Kaetzel (whose own career has changed dramatically in that same twelve months, but that's a story I'll let him tell). The article was long overdue, as we had been itching to start our blog for a very long time, but no one was ever able to quite make it a high enough priority to see it through. After the 4th retro in a row where Justin "You're Welcome" Thomas put "Blog" at the top of our "What we can improve" column during our monthly team retro, Kaetzel, Eisenhardt, and myself decided to finally do something about it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The first problem: Getting Started
&lt;/h2&gt;

&lt;p&gt;Kaetzel volunteered to write the first article, I would take the second, and Tim would help as an editor/reviewer/road-block destroyer for the time. That gave me time to look into hosting options and figuring out all of the other minutia involved with starting (and more importantly, running) a blog (unofficial hat number 2). In the end, we settled on &lt;a href="https://medium.com/dealeron-dev"&gt;Medium&lt;/a&gt; as our initial hosting platform. As you can tell, since you're likely reading this on Dev.To, our plans have since changed, but I'll get to that in a moment. &lt;/p&gt;

&lt;p&gt;We chose Medium initially due to the huge initial barriers it removed in the published blog format. It gave a very nice paradigm of "publications" where authors could contribute articles and editors could approve them, make corrections, and publish them on a schedule. It was great and worked well for our work flow. We could queue up a few articles in the down time between other major work we were doing which provided a nice buffer for when certain tasks became more complicated than we expected. &lt;/p&gt;

&lt;p&gt;The second major thing that made Medium a great initial choice was the syndication. Medium would push our articles out to people that were interested in the topics we wrote about. &lt;em&gt;Boom!&lt;/em&gt; Instant market share. It was a great way to get started and to get our content out in front of the people that would be most interested in it without requiring substantial marketing effort on our end, which isn't something we had a ton of time to spend on. We were essentially operating the blog as a skunk-works project in between all of the other regular commitments and expectations. This is the key point that lead to some of the substantial career changes I mentioned earlier. &lt;/p&gt;

&lt;p&gt;Over time, Medium rolled out various changes to their business model, some of which we didn't agree with, and some which seemed more user-hostile than we were willing to accept. No longer would our articles be sent out to users that were interested in our kind of content without us allowing the articles to be part of the Medium paywall, meaning readers would no longer be able to read our content for free, which was our goal. There wasn't even an option for us to pay instead of the readers. Due to these changes, along with a lack of features we were looking for in regards to sharing code (Medium's Gist support is terrible), I began looking for another hosting provider.&lt;/p&gt;

&lt;p&gt;As you can tell, I landed on Dev.To and so far it has been great, the features available much more align with our needed feature set, and the best part is that if there's a feature we really need that doesn't exist, we can contribute to it. Dev.To has been a great home and lead to more directed feedback and communication with some of our readers. &lt;/p&gt;




&lt;h2&gt;
  
  
  The second problem: Getting content
&lt;/h2&gt;

&lt;p&gt;The second major hurdle we would encounter on our journey to blog-dom was finding content. We have an ample group of very talented and capable engineers, but I've learned over the last year that getting that knowledge &lt;em&gt;out&lt;/em&gt; of their brains is a hundred times more difficult than getting it in there. &lt;/p&gt;

&lt;p&gt;Everyone hits that initial barrier of "I'm not a writer", and that brings me to my first lesson, and something I find my self needing to repeat to everyone participating in the DealerOn blog from time to time:&lt;/p&gt;

&lt;h3&gt;
  
  
  Everyone is a writer
&lt;/h3&gt;

&lt;p&gt;No matter your skill level, there's always someone that can stumble across your content that is learning that technology for the very first time today. You may be the inspiration that keeps them on the path of development when they're having doubts. You can be the voice of encouragement cheering them on, showcasing that "I too, had trouble learning this, here's what finally helped". Everyone, and I do mean everyone, has something to share. The best way to get started is to just begin writing. I find "&lt;a href="https://en.wikipedia.org/wiki/Stream_of_consciousness"&gt;Stream of Consciousness&lt;/a&gt;" writing to be a great starting point as it gets your mind into the right state after a few paragraphs of "I don't know what to write. This is so stupid. I feel like an idiot just sitting here talking to myself like this". I find it very similar to &lt;a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging"&gt;Rubber Duck Debugging&lt;/a&gt;, something that most of us have found helpful at some point or another. If you get stuck getting started, talk it out with someone. Just getting the words out of your head can help you substantially for figuring out how they fit into the picture you're painting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everyone needs encouragement
&lt;/h3&gt;

&lt;p&gt;Along with people having trouble starting an article, they often times have trouble finishing. They'll get a few paragraphs in and get discouraged, thinking their style is terrible or that there's nothing interesting there. That's where my job comes in. I'm the editor for every article that is published, which means I'm reading several articles a week to help with spelling, grammar, forming thoughts, and providing ideas when our authors get stuck. Everyone can use a little encouragement from time to time. &lt;/p&gt;

&lt;h3&gt;
  
  
  Keeping to a schedule is &lt;em&gt;tough&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;I thought it would be easy when we started this. I thought I was clever by giving everyone a "due date" that was two weeks prior to when I planned to publish their articles. That should have given enough time for them to remember the due date last minute, write the article, and have it ready a few days late so I could review it in time for publishing. That worked well enough for a few weeks, but they quickly caught on, and we quickly entered into an article deficit. Thankfully, I've had some amazing colleagues that seem to love writing and have no end of inspiration, so they have saved my bacon more than a few times by popping up at the last minute with a "hey, I was bored, so here's three articles I wrote last night". I started out with a schedule planned about 2 months out at a time, assigning articles to specific people that I thought would have something interesting to write about, or people that expressed interest in writing something. "Interest" and "Available time" rarely coincide. I eventually shifted to a "team-based" approach instead of individual people so that each team could prioritize and figure out among themselves who would have the time and interest in producing an article. So far that's worked out fairly well, and now every team knows they have an article due every 6 weeks. As we grow and add teams, that gap will grow accordingly. &lt;/p&gt;




&lt;p&gt;It became clear to me that with all of these substantial time sinks of problems related to running a blog, this wasn't something we could continue to manage as a skunk-works project. I spoke to my manager about finding a way to make this "official" and part of my regular job responsibilities so I didn't feel like I was sneaking around to do this all the time, especially when it was clearly something we wanted to do as a team. We sat down and detailed all of the "non-engineer" things I had taken on as day to day tasks and we established a new suffix that can be applied to titles to indicate a non-insignificant portion of their day to day will be spend on non-engineer related tasks. That took effect for me officially at the beginning of the year, about 3 months into our blog's life. Enter official hat number 2. &lt;/p&gt;

&lt;p&gt;With the suffix of "Developer Advocate" officially tacked on to me, I was able to spend more time planning and structuring out the blog without feeling guilty about it. (Other initiatives like GreenLight, "Tokens of Appreciation", OSS Policy, and others fell under that umbrella now too.) This lead to the changes I mentioned earlier like switching platforms and being able to set an official publication schedule. &lt;/p&gt;

&lt;p&gt;This leads me to lesson number 4:&lt;/p&gt;

&lt;h3&gt;
  
  
  For anything to work, it requires higher-up buy in
&lt;/h3&gt;

&lt;p&gt;Even though we now had regularly scheduled articles and had managed to publish an article every Friday since we established that's what we wanted to do, my authors were still feeling stressed out about their articles and being able to work on them during normal business time (something I was adamant about, along with each author receiving credit for their work and not publishing it under a "DealerOn" group pseudonym). The problem was that even though we were creating tickets in our normal work system for these items so time could be estimated and tracked right along with all the other items in a sprint, they didn't feel like they were actually allowed to. They needed reassurance from higher up that yes, this has been approved and you are allowed to do it. The Development Managers and I worked together to increase the transparency of the message and make sure that everyone knows they're allowed to work on these.&lt;/p&gt;

&lt;p&gt;Through a recent team adjustment into more domain focused teams (effectively, more scrum-ish groups, through which I gained another temporary hat of team lead), it will be easier to accommodate this work as part of the normal expectations from a team, and with the endorsement from on high, everyone knows that they are able to, allowed, and encouraged to work on their articles during work hours. It's not extra work, it's a different type of normal work. Of all the lessons learned this year, this is the largest that I wish I had picked up on earlier. I've caused a lot of undue stress and headaches for everyone involved by not ensuring it was explicitly clear and known by all parties involved (Devs, Managers, PMs, etc) that teams had this other work expectations as well.&lt;/p&gt;




&lt;p&gt;All in all, it's been a great year. We've published a ton of articles on a steady schedule right out of the gate, a cadence many did not expect us to be able to keep (and most of which we've managed to port over to Dev.To). We learned so much along the way and sparked that writing spirit in a number of our teammates. In the end, without the amazing determination of everyone involved in this project, we would not have been able to make it to today. We have one year under out belts now, and I'm looking forward to the ones ahead.&lt;/p&gt;

&lt;p&gt;Thank you team, this wouldn't have been possible without you all. &lt;/p&gt;

</description>
      <category>yearinreview</category>
      <category>writing</category>
      <category>career</category>
    </item>
    <item>
      <title>What is a Development tool?</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Fri, 05 Jul 2019 14:15:26 +0000</pubDate>
      <link>https://dev.to/dealeron/what-is-a-development-tool-46g</link>
      <guid>https://dev.to/dealeron/what-is-a-development-tool-46g</guid>
      <description>&lt;p&gt;Every developer and engineer has a different set of tools they use. Working primarily in the .NET landscape, my tools frequently include Windows, Visual Studio, VS Code, Git, etc. Typically, the more green a developer is, the more rigid their definition of a "development tool" and the fewer items they'll install when getting started. I'd like to introduce you to my process for getting a dev environment set up, tell you about some of the ways I use my "development tools" and possibly help expand your definition of "development tool" in the process.&lt;/p&gt;

&lt;h1&gt;
  
  
  Gitting Started
&lt;/h1&gt;

&lt;p&gt;At a new job, or when getting a new computer, developers are often presented with needing to set up their "Dev Environment". This can often be a tedious process, requiring numerous installs and a long, long wait time while everything gets configured. Starting with the blank slate of a newly installed and domain-attached can be daunting, especially for a new hire. Thoughts of "What do I install first?" and "Which items will make me productive the fastest?" often race into their minds while they desperately try not to look useless for the first several hours of their new job. &lt;/p&gt;

&lt;p&gt;It can be stressful, but I'll let you in on a little (slightly off topic) secret: &lt;strong&gt;No company expects you to be productive in the first few hours&lt;/strong&gt;. You're expected to learn and discover in that time frame. Asking questions, reading through the numerous documents and wikis you'll be presented with, and generally being curious is your job for the first day and often for the first week. &lt;/p&gt;

&lt;p&gt;In order to maximize that time that you're spending getting up to speed, there are some tools you can use to aide in setting up your computer while you're reading those docs and wandering around asking "what was the password for the WiFi again?". &lt;/p&gt;

&lt;h2&gt;
  
  
  Chocolatey
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://chocolatey.org/"&gt;Chocolatey&lt;/a&gt; is by far the #1 development tool I use. Not in the quantity of time I spend using it, but in the quantity of time I &lt;em&gt;save&lt;/em&gt; by using it. Combined with &lt;a href="https://gist.github.com/"&gt;Github Gists&lt;/a&gt;, you can have a very powerful combination that will save you an immense amount of time when setting up your new PC. You can browse and search through the full list of packages available here: &lt;a href="https://chocolatey.org/packages"&gt;https://chocolatey.org/packages&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chocolatey is essentially a package manager, similar to Brew on Mac or APT on Debian/Ubuntu. It allows installing and updating a vast number of programs via the command line or an optional user interface. It's simple to install and saves immense amounts of time when installing multiple programs at once, like when setting up a new computer. The typical set of packages I'll install on a new computer is shown in &lt;a href="https://gist.github.com/sohjsolwin/9e7f45ce150e7900f25be33b9ca08500"&gt;this gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;-y&lt;/code&gt; parameter attached to the Chocolatey command tells it to accept the packages as it's installing, otherwise you would need to type in &lt;code&gt;Y&lt;/code&gt; for each package in order for the installation to continue. Without that parameter, the unattended install we're trying to do becomes useless. &lt;/p&gt;

&lt;p&gt;While Chocolatey is happily churning away downloading and installing these packages, you're now free to spend your time reading up on that documentation or shadowing and asking questions from your fellow coworkers while your machine gets set up. The list of applications you install in this initial run of Chocolatey may not be every application you'll need in your development career, but it should take you most of the way there and allow you to be active while everything is getting set up instead of stuck there banging your head on the keyboard while the progress bar ticks forward on it's 12th minute of 37 seconds remaining. &lt;/p&gt;

&lt;h2&gt;
  
  
  VS Code
&lt;/h2&gt;

&lt;p&gt;I can hear you now. "&lt;a href="https://code.visualstudio.com/"&gt;VS Code&lt;/a&gt; is obviously a development tool." you say, and you're absolutely right. It &lt;em&gt;is&lt;/em&gt; already a development tool, but it's uses in development extend beyond just the IDE components it contains. &lt;/p&gt;

&lt;p&gt;While my primary development is done through Visual Studio, I always have a window of VS Code open along side it. Code has quickly become my favorite text editor and has surpassed Notepad++ for day to day usage. One of the primary things I'll do with it is text search. I'll open up the root folder where I check out all my repositories to and use the powerful, and fast, text search feature of Code to search through all of my repo's code at once. Often times I'm looking for usages of a table or package that might be shared across projects that I don't frequently work in or that my team doesn't maintain. Notepad++ used to be my &lt;code&gt;goto&lt;/code&gt; for this, but the search feature when looking across multiple files in multiple directories just became so slow and cumbersome that it was unusable. Thankfully, Code doesn't seem to have that problem at all and is able to search through everything in around 30-45 seconds, whereas N++ would typically take upwards of 15 minutes. &lt;/p&gt;

&lt;p&gt;Not only is Code good for searching through large amounts of text, but it's good for editing it too. &lt;/p&gt;

&lt;p&gt;While working through refactors, I'll often need to update a large amount of items from a switch statement or a large block of if statements at once. This can be quite tiresome to do individually by hand, but thanks to the robust multi-cursor capability of Code, I can make these edits in bulk instead of one by one. &lt;/p&gt;

&lt;p&gt;In the following example, we had several large switch statements operating off of Int values. There was also an Enum which contained these values but was unused in the switch statements for unknown (read: legacy) reasons. In a recent refactor, we had determined that the Enums would be better served by actual objects which contained all of the extra data we were constantly binding the Enum values to instead of keeping that explicitly related information spread across numerous locations. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I've changed a few of the names for this example, but the same principle and pattern is there. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n8l8qa5e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/u92dlb45f0palm61xreg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n8l8qa5e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/u92dlb45f0palm61xreg.gif" alt="" width="880" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above gif, you can see me using the multi-cursor ability to simultaneously remove all of the syntax surrounding the case statements, which I then copied into a mapping spreadsheet (more on that in a second) to link the enum values to the names needed for the new object-based class. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QR95o95w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8gizs5114qzp4o1l2hmu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QR95o95w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8gizs5114qzp4o1l2hmu.gif" alt="" width="880" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, I cleaned up the artifacts from the mapping spreadsheet and began turning each of the previous &lt;code&gt;case&lt;/code&gt; groups and &lt;code&gt;return&lt;/code&gt; statements into &lt;code&gt;if&lt;/code&gt; statements, using the name of the return value as part of the name for the list being evaluated in the &lt;code&gt;if&lt;/code&gt; statement. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--djQGYU1V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pmoqwcj9hpa1gm8zqlz5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--djQGYU1V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pmoqwcj9hpa1gm8zqlz5.gif" alt="" width="880" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then wrap each of the groups of cases in a &lt;code&gt;private static readonly&lt;/code&gt; array, using the same multi-cursors established based on the &lt;code&gt;return&lt;/code&gt; lines. Once they're all wrapped, I cut out the &lt;code&gt;if&lt;/code&gt; statement lines and group them together up top. &lt;/p&gt;

&lt;p&gt;From here, all that's left is to update the name of the variable in use on each of the new case group arrays to match the values in the &lt;code&gt;if&lt;/code&gt; statements at the top which is quick to do manually. I haven't found a good way to do that using multi-line cursors yet, but if you have an idea I'm interested to hear it. &lt;/p&gt;

&lt;p&gt;Taking this approach to the refactor makes it much less error prone in regards to typos or list transposition, and removes a fair amount of the human factor and fatigue related to looking back and forth between to walls of text trying to match items up. &lt;/p&gt;

&lt;h2&gt;
  
  
  Excel
&lt;/h2&gt;

&lt;p&gt;I mentioned a "mapping spreadsheet" earlier. For this, I'm using Excel. Since I knew I would have several of these large switch statements to convert, and that linking up an int to a name in a list is very tedious and error prone, I opted for creating a spreadsheet to help me out with this.&lt;/p&gt;

&lt;p&gt;I set up a "table" in the spreadsheet with 2 columns, one for the int value and one for the name. I then configured another column with a &lt;code&gt;VLOOKUP&lt;/code&gt; function to use that table to find and return the name based on the int specified in a fourth, input, column. I also added a &lt;code&gt;CONCAT&lt;/code&gt;function to the formula as well to put the results in a format closer to what I needed. &lt;/p&gt;

&lt;p&gt;The end result is a very useful tool for matching up a number of ints to their object-named values while removing the potential for a mis-type or bad copy/paste. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tRUkA6Cv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/k8di3ohdk24va9tq8yte.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tRUkA6Cv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/k8di3ohdk24va9tq8yte.gif" alt="" width="676" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last step is to copy both columns, since the formula column has the value you actually want, but the input column has the return statements in them, and paste back into your text editor over the top of the previous input.&lt;/p&gt;

&lt;p&gt;I use Excel frequently when I need to do large lookups like that, or when I'm needing to work with or manipulate various amounts of data. The &lt;code&gt;CONCAT&lt;/code&gt; and other similar functions are useful for building groups of &lt;code&gt;switch&lt;/code&gt; or &lt;code&gt;if&lt;/code&gt; statements, SQL scripts, and any other type of script or code block that has a number of separate values you need to combine in some way.&lt;/p&gt;

&lt;h1&gt;
  
  
  Commit to memory
&lt;/h1&gt;

&lt;p&gt;These were a couple of the tools I find myself using frequently alongside the more traditional "development tools" like Visual Studio or Git. I've found them immensely useful over the years and have saved myself considerable time by learning how the tools in my toolbox can be used and abused in interesting ways. Admittedly, the uses I described above are some of the tamer uses for tools, but still useful nonetheless. What are some tools that you use in non-standard or unintended ways. I'm interested to see, and learn, some new tools I can add to my list.  &lt;/p&gt;

&lt;p&gt;Cover photo by: &lt;a href="https://unsplash.com/@pjswinburn?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge" rel="noopener noreferrer" title="Download free do whatever you want high-resolution photos from Philip Swinburn"&gt;&lt;span&gt;Philip Swinburn&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>csharp</category>
    </item>
    <item>
      <title>🅲🅴🅽🆂🅾🆁🅴🅳</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Fri, 08 Mar 2019 14:01:00 +0000</pubDate>
      <link>https://dev.to/dealeron/-1d9a</link>
      <guid>https://dev.to/dealeron/-1d9a</guid>
      <description>&lt;p&gt;Sometimes, when we’re working with data, we need to be sensitive with regards to what we’re exposing when we serialize our objects. On a recent project, I was dealing with various types of Personally Identifiable Information, often abbreviated as PII, and needed to find a consistent, and easy, way to mark fields as sensitive. I discussed the problem with my team and after a few rounds of spit-balling and bouncing ideas off each other, the &lt;code&gt;CensoredContentAttribute&lt;/code&gt; was born.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; All the code discussed in this article can be found in this &lt;a href="https://gist.github.com/sohjsolwin/cbce1999dd76fd15f583c9420f531dd9"&gt;&lt;strong&gt;Gist&lt;/strong&gt;&lt;/a&gt;. Eventually, I plan to set it up in a repo with some other useful classes and snippets, but for now, GitHub Gist is its home away from home.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To start, let’s preview an example of how this attribute works in practice.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The important bits are on line 9, &lt;code&gt;[Redacted(ShowFirst:3, ShowLast:3)]&lt;/code&gt;, and on line 13 &lt;code&gt;new CensoredJsonSerializerSettings&amp;lt;RedactedAttribute&amp;gt;()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Adding the &lt;code&gt;RedactedAttribute&lt;/code&gt; to the Name property of this &lt;code&gt;LoggingExample&lt;/code&gt; class sets it up to be read in when we go to serialize this class later on in the &lt;code&gt;ToSerializedString&lt;/code&gt; method. The &lt;code&gt;ShowFirst&lt;/code&gt; and &lt;code&gt;ShowLast&lt;/code&gt; properties of the &lt;code&gt;RedactedAttribute&lt;/code&gt; provide us a way to specify how many characters at the start and end of the original value should be shown in the serialized output. Very handy when serializing things like Social Security Numbers, Email Addresses, Phone Numbers, or Usernames where some fields may have different amounts of data permissible to view and others need to be fully censored.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;CensoredJsonSerializerSettings&amp;lt;T&amp;gt;&lt;/code&gt; is a class derived from &lt;code&gt;JsonSerializerSettings&lt;/code&gt; with constraints on the type of &lt;code&gt;T&lt;/code&gt;, limiting it to children of the &lt;code&gt;CensoredContentAttribute&lt;/code&gt;. This class helps to provide the necessary &lt;code&gt;ContractResolver&lt;/code&gt; to the &lt;code&gt;JsonSerializer&lt;/code&gt; so that your censored fields are handled properly.&lt;/p&gt;

&lt;p&gt;Next, we move on to the core of the attribute, with the &lt;code&gt;CensoredContentAttribute&lt;/code&gt;, &lt;code&gt;CensoredContentContractResolver&amp;lt;T&amp;gt;&lt;/code&gt;, and the &lt;code&gt;CensoredContentValueProvider&lt;/code&gt;. Here’s the code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Lines 8–13 are the abstract &lt;code&gt;CensoredContentAttribute&lt;/code&gt;, which defines a base class for us to attach most of our logic to, and more importantly, gives us a strong type to attach our &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters"&gt;generic type constraints&lt;/a&gt; to. It’s a simple class with one read only property, &lt;code&gt;Censor&lt;/code&gt;, and one method, &lt;code&gt;TruncateData(string input)&lt;/code&gt;. The Censor property is for defining what value will be used to censor the content. In our example attribute, &lt;code&gt;RedactedAttribute&lt;/code&gt;, we use the value &lt;code&gt;***REDACTED***&lt;/code&gt;. Similarly, the &lt;code&gt;TruncateData&lt;/code&gt; method does what it says on the tin, it’s for performing the actual truncation of your data.&lt;/p&gt;

&lt;p&gt;Lines 15–28 (technically through 50, as the &lt;code&gt;CensoredContentValueProvider&lt;/code&gt; is an internal class, but we’ll get to that in a moment) make up the core of the &lt;code&gt;CensoredContentContractResolver&amp;lt;T&amp;gt;&lt;/code&gt; class. This class is what the Netwonsoft Json Serializer is going to use to determine if a member on the object being serialized should use the default value provider, or if it should use our custom &lt;code&gt;CensorContentValueProvider&lt;/code&gt;. Overall, it’s pretty straight forward and ensures, through reflection, that the member we’re getting the value of has a child of the &lt;code&gt;CensoredContentAttribute&lt;/code&gt; on it. We get a reference to that custom attribute and pass it into the constructor of the &lt;code&gt;CensorContentValueProvider&lt;/code&gt; along with a reference to the standard &lt;code&gt;MemberValueProvider&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Lines 30–49 make up the &lt;code&gt;CensorContentValueProvider&lt;/code&gt; class, where the real magic happens. In here, we have a couple properties for holding references to the values passed in, namely the base &lt;code&gt;IValueProvider&lt;/code&gt; and the concrete implementation of our attribute, wrapped in a &lt;code&gt;CensoredContentAttribute&lt;/code&gt; shell. In the &lt;code&gt;GetValue&lt;/code&gt; method (line 39), we first need to pull out the string value of the member being censored. It’s a standard call to the &lt;code&gt;GetValue&lt;/code&gt; method of the &lt;code&gt;IValueProvider&lt;/code&gt; interface, but we need to make sure to toss in some null check and null coalescing so we don’t error out if the member hasn’t been set. After that, we throw our &lt;code&gt;targetString&lt;/code&gt; into the &lt;code&gt;TruncateData&lt;/code&gt; method of our attribute class and return the result.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;SetValue&lt;/code&gt; method isn’t particularly important in this case, since this is intended as a one way censoring attribute, but there are plenty of interesting things you could do there, including things like encryption when serializing to/from json. I’m interested to see what ideas you have. Let me know in the comments what you come up with.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That covers the groundwork and the core of our censorship engine, so now lets dive in to a couple example attributes. Here’s the code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Starting with the &lt;code&gt;LargeDataAttribute&lt;/code&gt;, we have an example use case for the &lt;code&gt;CensoredContentAttribute&lt;/code&gt; that doesn’t involve direct censorship for privacy reasons, but rather for log size reasons. In our case, we were trying to store a raw copy of the body from an &lt;code&gt;HttpRequest&lt;/code&gt; during development for debugging and replay purposes, but for some requests which included file uploads, this was excessively large. Utilizing the &lt;code&gt;LargeDataAttribute&lt;/code&gt; we were able to specify a threshold over which the data on the decorated member would be replaced with a message like “&lt;code&gt;***Large Data Removed*** [Length: 1024]&lt;/code&gt;”. This greatly eased the burden on our logging tools, and provided an easy way to get a general feel for what was included without being excessively large.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;RedactedAttribute&lt;/code&gt; is by far our most used of the two attributes though. With it, we are able to flag members as &lt;code&gt;Redacted&lt;/code&gt; and specify a varying amount of data that is okay to display in the logs when serialized. In the &lt;code&gt;TruncateData&lt;/code&gt; method, we check to ensure that the combined length of the first and last characters to show do not exceed the length of the original input. If it does, we spit out the value of the &lt;code&gt;Censored&lt;/code&gt; property only (&lt;code&gt;***REDACTED***&lt;/code&gt; in this case). Otherwise, we append the first X (where X is the value of &lt;code&gt;ShowFirst&lt;/code&gt;) characters of the input to our output string, append the &lt;code&gt;Censor&lt;/code&gt; value, then perform the same action for the number of characters specified by the &lt;code&gt;ShowLast&lt;/code&gt; property. Finally, we run one final sanity check on the output and return the value, or the &lt;code&gt;Censored&lt;/code&gt; value, if our planned output was somehow empty. This ensures that someone looking at the log does not know if the original input value was originally empty, or contained less characters than the supplied &lt;code&gt;Censor&lt;/code&gt; string (that the reason the &lt;code&gt;Censor&lt;/code&gt; string is padded with asterisk as well).&lt;/p&gt;

&lt;p&gt;Packaging it all together, you end up with a pretty straight forward way to mark members of your classes as sensitive and perform some form of modification to the data before putting it through serialization. If you need to serialize the same object without the redaction, such as for writing to a DB, posting to an endpoint, or writing out to a file, you simply run it through the serializer without sending in the &lt;code&gt;CensoredJsonSerializerSettings&lt;/code&gt;. Additionally, the &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt; value of the &lt;code&gt;CensoredJsonSerializerSettings&lt;/code&gt; allows you to use multiple children of the &lt;code&gt;CensoredContentAttribute&lt;/code&gt; in a single class and optionally trigger specific censor attributes based on the value you send in as &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt;. For example, we use the &lt;code&gt;&amp;lt;RedactedAttribute&amp;gt;&lt;/code&gt; value for &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt; when serializing for logs, and the &lt;code&gt;&amp;lt;LargeDataAttribute&amp;gt;&lt;/code&gt; when serializing for the DB.&lt;/p&gt;

&lt;p&gt;Custom attributes provide a world of options and capabilities that every developer tends to find their own unique way of using. The &lt;code&gt;CensoredContentAttribute&lt;/code&gt; is just one of the custom attributes we utilize here at &lt;a href="http://jobs.dealeron.com"&gt;DealerOn&lt;/a&gt; and I plan on covering more of our helpful snippets and libraries in the future. Thanks for checking this out, and I look forward to reading how you are utilizing custom attributes in you’re own projects.&lt;/p&gt;




</description>
      <category>softwaredevelopment</category>
      <category>programming</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>… And that brings us to today</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Fri, 02 Nov 2018 13:01:01 +0000</pubDate>
      <link>https://dev.to/dealeron/and-that-brings-us-to-today-5cf3</link>
      <guid>https://dev.to/dealeron/and-that-brings-us-to-today-5cf3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a8Ls606x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AW92cCNO0ie8HqI51UYwveQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a8Ls606x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AW92cCNO0ie8HqI51UYwveQ.png" alt=""&gt;&lt;/a&gt;DealerOn Lobby&lt;/p&gt;

&lt;p&gt;If you were to look at the DNA of DealerOn under the microscope, you’d see base pairs of &lt;strong&gt;Opportunity&lt;/strong&gt; , &lt;strong&gt;Ownership&lt;/strong&gt; , &lt;strong&gt;Camaraderie&lt;/strong&gt; , and &lt;strong&gt;Determination&lt;/strong&gt; comprising the genes that are directly responsible for the success and rapid growth DealerOn has experienced over the last decade.&lt;/p&gt;

&lt;p&gt;Rolling the clock back to around 2012-2013 and you’ll find a young &lt;strong&gt;Jon Rothbard&lt;/strong&gt; and &lt;strong&gt;Tim Eisenhardt&lt;/strong&gt; just getting started at what will turn out to be challenging, yet rewarding careers. Tim and Jon cast some of the longest shadows here at DealerOn and were largely influential in setting up the current culture and “family oriented” mentality that has become a staple of our everyday work life. When asked about the roles they played along the way, Jon simply replied &lt;em&gt;“What roles didn’t we play?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--65WNAXyf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/429/1%2A0Gisa2M1JG9G1Fw0C9XJGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--65WNAXyf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/429/1%2A0Gisa2M1JG9G1Fw0C9XJGg.png" alt=""&gt;&lt;/a&gt;Tim Eisenhardt, Principal Solutions Architect&lt;/p&gt;

&lt;p&gt;Tim will grow to be the &lt;strong&gt;Principal Solutions Architect&lt;/strong&gt; of the Development Team, and Jon will skyrocket to the position of &lt;strong&gt;VP of Operations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But in 2012, Jon is making his mark as a &lt;strong&gt;Junior Web Designer&lt;/strong&gt; , and by coincidence of where the last open desk was, &lt;strong&gt;Front Desk Clerk&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Meanwhile, Tim, a recent casualty of the Government shutdown, is starting his position as a &lt;strong&gt;Junior Developer&lt;/strong&gt; , with no clue what to do and a fresh heap of gratitude for being given a chance to prove himself, despite lacking any real development experience.&lt;/p&gt;

&lt;p&gt;Shortly after starting, Tim is approached with the task of converting the entire Platform of DealerOn (responsible for serving up the websites and inventory for a large number of automotive dealerships) from a Flex-based system into a new Responsive-based one, something that very few web platforms, and no competitors, have accomplished at the time. Tim has no idea where to begin, but riding on the high of all the trust that is being placed in him, he rose to the occasion and saw the project through to completion in record time. This is Tim’s first taste of the level of ownership possible in projects at DealerOn.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A shared sense of ownership, to me, is the best driver of quality. Period.” — Tim&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1FS0EAVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/423/1%2AW7xfI8rBo3H8IKIBj-W7PQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1FS0EAVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/423/1%2AW7xfI8rBo3H8IKIBj-W7PQ.png" alt=""&gt;&lt;/a&gt;Jon Rothbard, VP of Operations&lt;/p&gt;

&lt;p&gt;Fast forward a few years and DealerOn has hit numerous growth milestones by taking on several new OEMs (original equipment manufacturers)and large dealership groups like AMSI as customers. Jon is now running no less than 4 different departments; DealerOn is in the middle of some department shuffling and division in order to better position itself to handle the rapid growth it’s experiencing, like the break out of Creative Operations from the Design group, and the formation of a QA team; and Tim is now Lead over the entire development team, which has exploded to nearly 3–4 times the size it was when he started.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Jon and I have lamented plenty of times over the years that this growth pattern is just unprecedented and unmetered, and to be able to account for that we’ve had to do some stuff that we would all agree were hacks, and bear the brunt of that technical debt as the time came. “ — Tim&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s a crazy, hectic time at DealerOn. Code’s flying left and right, features are going up, bugs are going down, and commits are at an all time high. Knowing the current pace isn’t sustainable indefinitely, Tim and Jon set forth a goal to keep quality up while keeping throughput high:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“To ensure we are not only creating new, quality products, but also facilitating the quality of life improvements for our employees, as well as our clients.” — Jon&lt;/p&gt;

&lt;p&gt;“Finding the communications channels and the strategic channels to make that live side by side with new features, and requests for customers, and stuff that’s coming from new contracts” — Tim&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that brings us to today. I managed to track down these two titans of DealerOn and asked them a few questions about their time here, their thoughts on the company and it’s journey, and their goals and perspectives on teamwork, team growth, and the culture they’ve helped to foster.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interviewer:&lt;/strong&gt;  &lt;strong&gt;To begin with, can you each state your name, title, and how long you’ve been here.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jon:&lt;/strong&gt; My name is Jon Rothbard, I have been here for 6 years, and my title is currently VP of operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tim:&lt;/strong&gt; Tim Eisenhardt, I’ve been here for 5 years, Principal Solutions Architect&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I: And what were your titles when you started?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;J:&lt;/strong&gt; Junior Web Designer&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; Junior Developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I: Okay, first question. What does DealerOn mean to you?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;J:&lt;/strong&gt; What does it mean now, or what did it mean then?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I: Your call.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; What does it mean to me professionally or personally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I: Again, it’s your answer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;J:&lt;/strong&gt; Right, I think my answer is a combination of both, for the fact that DealerOn is a collective family built on a culture that has brewed into what its turned into&lt;br&gt;&lt;br&gt;
today; of a technology company that is cutting edge…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; And to me it’s opportunity. Right, because we have the desire to be family-cultured, and to be results oriented, we don’t treat any idea as a bad idea until we’ve vetted it and gone through it, and we don’t treat any candidate as though they’re a bad candidate until we’ve seen what they have to offer.&lt;/p&gt;

&lt;p&gt;When I joined, I’d just been laid off because of the impending government shutdown. I found the job because the job posting said all levels, which was my keyword search on the job boards. And they kind of saw that I had potential, despite having no on-paper experience in the field, and gave me a shot.&lt;/p&gt;

&lt;p&gt;And that inspired me to work hard. And they also encouraged me when I had ideas that I wanted to flesh out, or wanted to try and do new things, to see where those lead, despite the fact that the growth was insane and there was always too much work to do anyway. And I think that that’s persisted over the 5 years.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the topic of DealerOn’s milestones, and which ones stood out the most, Tim and Jon were in agreement that bringing on a new OEM is a significant milestone each and every time. The continued growth of departments, and formation of new departments, the Training department being the most recent, are also significant milestones that speak to the growth of the company as a whole, and not just the development-related departments. In addition, formalizing our product catalog with the newly formed Product department has been substantially beneficial. A product catalog helps spread the use of more ubiquitous language across all levels of the company and minimize communication barriers between the technical and non-technical staff.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“[B]y force of sheer will … it’s evolved at each of these kind of checkpoints.&lt;br&gt;&lt;br&gt;
 …&lt;br&gt;&lt;br&gt;
We’ve had to find procedural and programmatic and technical solutions to the problem of scale and rapid growth.” — Tim&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tim reflected on the formation of the Product department and recalled what it was like in the early days, stating that &lt;strong&gt;“… (Chief Creative Officer, Michael)&lt;/strong&gt;  &lt;strong&gt;DeVito &lt;em&gt;WAS&lt;/em&gt; the product department, and Jon and I made sure whatever came out of his face was implemented.”&lt;/strong&gt; Management and Leadership from within the Development team are additional key milestones for the group, allowing the large pool of technical expertise contained within the team to be cultured into &lt;em&gt;“leadership roles and be[ing] a part of the decision making process.”&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The fact that people go out of their way to mentor each other, go out of their way to help each other when, you know, the shit hits the fan” — Tim&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When asked about any sacrifices made along the way, Tim and Jon replied in unison: &lt;strong&gt;Time&lt;/strong&gt;. Getting to the place they’re at professionally in their careers, and collectively as a company required immense sacrifices of time over the years. Stepping back from their professional passions and stepping into the necessary roles to “steer the ship”, as it were, was a necessity. Sometimes things don’t go to plan, and you have to step back, assess, and react. Tim recalled an instance just over a year ago:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We had concrete positions filled in QA and DevOps, full time, where we’d finally gotten head count and done a lot of interviewing and get those people in. And fast forward a couple of months, they were both open head count again which meant that those roles fell to us and so we couldn’t focus on architecting solutions for the future, we had to get back in there and solve some more day to day problems, just to make sure that stuff kept running smoothly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It all comes back to ownership, being able to accept a problem, identify a solution, and owning that implementation. DealerOn is &lt;em&gt;“being able to kind of be the master of your own destiny. … It’s opportunity to make a name for yourself, to work on what you want to work on, to make sure that things are done the way that you feel is best.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One quote that I felt described that mentality the best came towards the end of our interview:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Everybody buying in, understanding that you may have a disagreement, you may have a flawed assumption …, but if you’re all on the same page about what the objective is, and that you all have group ownership over reaching that objective, you’re going to have a high quality product at the end of it.” — Tim&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The forward momentum isn’t over yet though. One of Jon’s goals for the development team is more self-sufficient teams, allowing for Tim and himself to move farther out of the day to day details of the work and focus more on big picture strategy and long term goals of the company. Giving teams the bandwidth and resources they need to accomplish the individual team’s goals enhances the overall department and company trajectories by improving autonomy and reducing inter-departmental and cross-team abrasion that too many layers of process can cause.&lt;/p&gt;

&lt;p&gt;As a final note, I asked Tim and Jon to address future readers directly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; I think the key word is opportunity. I think you’d be hard pressed to find somebody that’s been here for a considerable amount of time, that they couldn’t point to at least one chance where there was a meeting where it didn’t matter that they were brand new to the company or whatever it was, and their voice was heard and really felt equal.&lt;/p&gt;

&lt;p&gt;Because we try to make that the feeling from the top down. We don’t care if you’re here 90 days, we don’t care if you’ve had 20 years of experience, or no years of experience, &lt;strong&gt;being able to solve problems, make suggestions, and be a part of the solution is the most important thing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;J:&lt;/strong&gt; Yeah, being a part of the solution is a good way of saying it. People do have a voice, but it’s also you can make your own destiny. You can start like me and Tim have, … we [the company] have grown a lot, but you still have the opportunity to do the same thing.&lt;br&gt;&lt;br&gt;
If you want to work your way up the ranks, or if you want to create a new department: Often someone may mention that they have ideas that we should spin up a new department, for Training or for QA or such and so on and so forth. &lt;strong&gt;[Anyone] could do that if they have the drive and motivation to want it and build it.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
…&lt;br&gt;&lt;br&gt;
We have a developer that wanted to switch from Development to Product, so there’s plenty of opportunities regardless of what track. And if you want to start as one, you can always hop over to another.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; Yeah, there’s no shortage of people on the Development team that started in Customer Support positions; there’s no shortage of people on the Graphic Design team that started in support positions; and there’s people, we were just in a meeting, basically an executive level meeting, talking about customer retention and &lt;strong&gt;everybody in the room started as a junior employee in one team or another&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a final shout out to the folks at DealerOn that have made this journey possible, Jon had this to say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This goes without saying: we could not have done this without the support of the initial hard working, dedicated execs at DealerOn. Shout out to the b &lt;strong&gt;rothers&lt;/strong&gt; [CEO/Co-Founder, Ali A. and Co-Founder Amir A.], [Chief Operating Officer] Amir S., [Chief Creative Officer, Michael] DeVito and [VP of Customer Experience, Mike] Somerville who’ve been along for the ride with us and made the company what it is today. (Sorry if I left anyone out)” — Jon&lt;/p&gt;
&lt;/blockquote&gt;




</description>
      <category>backstory</category>
      <category>startup</category>
    </item>
    <item>
      <title>Golang and the Mirror-Quickstart</title>
      <dc:creator>Josh</dc:creator>
      <pubDate>Thu, 27 Sep 2018 18:23:24 +0000</pubDate>
      <link>https://dev.to/sohjsolwin/golang-and-the-mirror-quickstart-299b</link>
      <guid>https://dev.to/sohjsolwin/golang-and-the-mirror-quickstart-299b</guid>
      <description>&lt;p&gt;I’ve been struggling to get the &lt;a href="https://github.com/googleglass/mirror-quickstart-go"&gt;Mirror-Quickstart-Go&lt;/a&gt; up and running. A few months back I was able to get it running on an appengine instance without any trouble at all. Recently though, I decided to blow away the test code I had on my appengine and start over. Unfortunately setting up the quickstart was not as easy this time. After following the usual steps of setting up a project, creating the client IDs and configuring the project with the proper information, I deployed it and became stuck in an authorization redirect loop. The only error I received in the Log viewer was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get Token: datastore: no such entity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After double and triple and quadruple checking that I had all the right IDs everywhere, I figured out a way to be able to debug the project and start tracking down the issue. There are only a handful of URLs that the quickstart is configured to handle. Anything else and it will just return a 404 error, as it should. I decided to use this to my advantage by modifying the main.go file to change all of the sections that performed HTTP redirects to redirect to pages such as “/useridempty”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**if** userId **==**"" {
 //http.Redirect(w, r, "/auth", http.StatusFound)
 http.Redirect(w, r, "/useridempty", http.StatusFound)
 **return**  **nil**  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allowed me to track it down to line 84: t := authTransport(c, userId) authTransport was returning nil. Continuing this into the util.go file, the line that was causing trouble was line 94, specifically the datastore.Get(c, key, tok) portion. Turns out, that the token needed to authenticate wasn’t being stored in the database, to the error (and subsequently the redirect) being caused by this was accurate.&lt;/p&gt;

&lt;p&gt;I went back to the oauth2callback method, since I knew that was getting called at least, and visually stepped through the code cross referencing what was happening with what the code should be doing. This lead me to the storeCredential method. The storeCredential method (used on line 78 in the auth.go and declared on line 83 in util.go. The storeCredential method returns an error, but that error was not being checked. I modified the usage of storeCredential in the auth.go file to return the error like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if err = storeCredential(c, userId, tok); err != nil {
 return fmt.Errorf("Unable to store credential: %s", err)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This resulted in the following error: Unable to store credential: datastore: unsupported struct field type: map[string]string&lt;/p&gt;

&lt;p&gt;After some digging around, I found that storing map objects in the datastore is no longer supported. I’m not sure exactly when it became unsupported, but the fact of the matter remains that it just plain won’t work any more. The Token object from the oauth2 library contained an “Extras” field of type map[string]string and since it was a Token object that was being stored in the datastore, that’s why it’s failing. The token never got saved, so of course it wasn’t there when it tried to read it out, but with the way the demo was calling the storeCredential method, the error was being dropped and passing by silently.&lt;/p&gt;

&lt;p&gt;In order to fix the error, I created a simple “SimpleToken” struct that contained the same signature as the Token object, just without the “Extras” field. I also set up a couple of short methods to turn a oauth.Token into a SimpleToken and vice versa. In the util.go file, I changed the storeCredential method to take in a *SimpleToken instead of a *oauth.Token and the authTransport method to convert the oauth.Token object into a SimpleToken object before passing it to the datastore.Get method. In the auth.go file, the only thing that had to change was in the oauth2callbackHandler method. The method was updated to convert the oauth.Token object into a SimpleToken object before the call to storeCredential.&lt;/p&gt;

&lt;p&gt;Once these changes were completed and the project redeployed to AppEngine, everything loaded up properly and began working. It was a very annoying issue and troublesome to track down, but once the root problem was found, the fix was surprisingly simple. Once I get around to cleaning up the code a bit I’ll fork the project and make a pull request so that anyone else pulling down the Go quickstart won’t have these same issues. I’d hope that the oauth or datastore library would be updated to properly work around the change to the datastore that now prevents storing map types.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published October 26, 2013 at&lt;/em&gt; &lt;a href="http://blog.sohjsolwin.com/2013/10/helpouts-meetups-and-mirror-qucikstart.html"&gt;&lt;em&gt;blog.sohjsolwin.com&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
