Jeremy Clark
Developer Betterer
Vancouver, Washington, United States
Actions
Jeremy helps developers by sharing his own struggles, mostly in technology, but also with being more social as an introvert, understanding potential for learning, and playing banjo. He has worked as a corporate developer, as a Chief Improvement Officer at a startup, and as a contract developer. Currently, he teaches developers through online courses, workshops, tech articles, and conference talks. He spends most of his time in C# and has recently ventured into Go (golang) and Rust (rust-lang) to explore some of his favorite topics: interfaces, delegates, concurrency, and parallel programming.
Links
Area of Expertise
Take Your C# Skills to the Next Level [Workshop]
Are you a C# developer eager to create software that is easy to maintain, has minimal bugs, and makes your users happy? This workshop is for you.
Through lectures, code samples, and hands-on labs, you will learn how interfaces, delegates, dependency injection, and unit testing can help you write applications that are easy to extend, change, and debug. Along the way you will also encounter modern C# topics such as nullability, switch expressions, and asynchronous code. In the end, you will take away practical experience that you can immediately apply to your own projects.
Workshop Topics:
o Interfaces: Explore the art of writing clean, modular code through interfaces. Learn how interfaces facilitate code extension, make your applications more testable, and lead to fewer bugs.
o Delegates: Gain a deep understanding of delegates and learn how to use them to build flexible and extensible code.
o Dependency Injection: Discover the magic of dependency injection and how it promotes loose coupling, making your codebase more flexible, testable, and maintainable.
o Unit Testing: Write tests that ensure your code functions as expected, enabling you to catch bugs early in the development process.
Key Benefits:
o Easier Maintenance: Explore practices for writing clean, maintainable code that's a breeze to work with, whether you're collaborating with a team or revisiting your own projects down the road.
o Fewer Bugs: Learn the art of writing robust code that is easy to test. Find bugs before your users do, and be confident that code changes do not break existing functionality.
o Happier Users: The point of writing software is to meet your user's needs. With these tools in hand, you can create applications that not only meet but exceed user expectations.
Pre-Requisites:
Basic understanding of C# and object-oriented programming (classes, inheritance, methods, and properties). No prior experience with the primary topics is necessary; we'll take care of that as we go.
Take your C# development skills to the next level and build software that not only satisfies your users, but also simplifies your life as a developer. Say goodbye to frustrating bugs, hello to happier users, and welcome to the world of painless maintenance.
Catching Up With C# Interfaces: What You Know May Be Wrong
C# 8 & C# 11 brought new features to interfaces, but many where not well publicized -- including default implementation, member access modifiers, and static members. The Microsoft documentation is correct, but many other C# resources have outdated information. So let's look at these changes and see where they are useful and where they should be avoided. The world of interfaces has changed; the line between interfaces and abstract classes has blurred; and C# now has multiple inheritance (sort of). With some practical tips, "gotchas", and plenty of examples, we'll see how to use these features effectively (and safely) in our code.
Safer Code: Nullabilty and Null Operators in C#
New projects in C# have nullable reference types enabled by default. This helps make the intent of our code more clear, and we can catch potential null references before they happen. But things can get confusing, particularly when migrating existing projects. In this session, you will learn about the safeguards that nullability provides as well as the problems you still need to watch out for yourself. In addition, you will learn the various null operators in C# (including null conditional, null coalescing, and null forgiving operators). These can make your code more expressive and safe.
LINQ - It's Not Just for Databases
LINQ (Language Integrated Query) is mostly associated with Entity Framework and database access. But it can be used for much more. LINQ lets us sort, filter, and aggregate data all in memory without needing to make another database call. In this session, we will build up an application that manages my book collection, including filtering, grouping, sorting, and even controlling how items are sorted. We will use the LINQ fluent syntax to combine functions and make a great user experience.
Code is for Humans
The computer understands your code just fine. But what about humans? The world is constantly changing, and your applications need to change with it. Humans make those changes; sometimes it's you, sometimes it's someone else. So let's look at some practical techniques to keep code readable, such as working in small pieces, coming up with good names for methods and objects, and avoiding "clever" code. Think about the next developer who needs to change this code. Often that developer is you from six months in the future. Your future self will thank you.
Get Comfortable with .NET and the CLI
Command-line interfaces (CLI) can be very powerful. The same is true in the .NET world. So let's get comfortable with creating, running, and testing applications using the command-line interface. We'll create a self-hosted web service and then write an application to use that service. Unit tests will make sure things work along the way. Whether you're new to .NET or have been using .NET with Visual Studio, this session will help you get up-to-speed in this powerful environment.
Focus on the User: Make the World a Better Place
Our job as developers is to make the world a better place, whether it's connecting people, providing entertainment, or making someone's job easier. We have to know who we're building software for: our users. Understanding my users has been a key to every successful project I've worked on. I'll share some of my successes and some of my failures, and show how that's led to the approach to software that I take today. Together, we can provide our users with just what they need to make their world a bit better.
Better Parallel Code with C# Channels
Producer/consumer problems show up in a lot of programming scenarios, including data processing and machine learning. Channels give us a thread-safe way to communicate between producers and consumers, and we can run them all concurrently. In this presentation, we will explore channels by comparing parallel tasks with continuations to using a producer/consumer model. In the end, we'll have another tool in our toolbox to help us with concurrent programming.
A Tour of Go for the C# Developer
Learning other programming languages enhances our work in our primary language. From the perspective of a C# developer, the Go language (golang) has many interesting ideas. Go is opinionated on some things (such as where curly braces go and what items are capitalized). Declaring an unused variable causes a compile failure; the use of "blank identifiers" (or "discards" in C#) are common. Concurrency is baked right in to the language through goroutines and channels. Programming by exception is discouraged; it's actually called a "panic" in Go. Instead, errors are treated as states to be handled like any other data state. We'll explore these features (and others) by building an application that uses concurrent operations to get data from a service. These ideas make us think about the way we program and how we can improve our day-to-day work (in C# or elsewhere).
A Banjo Made Me a Better Developer
What does a banjo have to do with software development? They both require learning. And picking up a banjo later in life showed me 3 things that I've brought into my developer life. (1) You can learn; a growth mindset removes blockages. (2) You don't have to be afraid to ask for help; experienced banjoists/developers can point you in the right direction. (3) You don't have to be perfect before you share what you've learned; it's okay to show what you have "in progress". In combination, these have made me a better banjo player and a better developer.
Abstract Art: Getting Abstraction "Just Right"
Abstraction is awesome. And abstraction is awful. Too little, and our applications are difficult to extend and maintain. Too much, and our applications are difficult to extend and maintain. Finding the balance is the key to success. The first step is to identify your natural tendency as an under-abstractor or an over-abstractor. Once we know that, we can work on real-world techniques to dial in the level of abstraction that is "just right" for our applications.
ASP.NET MVC Conventions: Your Secret Decoder Ring
ASP.NET MVC is filled with hidden conventions: put a controller or view in a certain place and give it a special name, and it magically works. If you know the conventions, you can quickly get an application up and running. But if you don't know the secret codes, all is lost. In this session, you will learn the conventions of ASP.NET MVC around controllers, views, parameters, layouts, and routing. Once you have the decoder ring, you can focus on the parts of your web application that make it unique.
Becoming a Social Developer: A Guide for Introverts
This is NOT a highly-interactive workshop. Now that you feel a bit safer, make the most of your time this week: talk to other developers. This is easy -- and incredibly terrifying. A few simple steps (and a bit of bravery) is all that it takes to get started. Building your developer network will boost your knowledge, your skills, and your career. Can an introvert become a social developer? YES! And we can do this while staying true to ourselves.
Design Patterns: Not Just for Architects
Design patterns are not just for architects. In fact, you already use design patterns without even knowing it. Observer, Facade, Iterator, Proxy -- these are just a few of the patterns that you have probably used. But it is really hard to use a tool effectively when you don't even know you are using it. So let's fix that.
In this session, you will learn what design patterns are (and what they are not). You will see both the benefits and consequences of patterns. And you will see several of the Gang of Four patterns that use already use (they may even be built into your programming language). Don't know who the Gang of Four is? You'll learn that, too. Once we understand design patterns, we can find solutions that people way smarter than us have already implemented. This gives us another set of tools that we can use to build great software.
DI Why? Getting a Grip on Dependency Injection
Most developers are introduced to dependency injection (DI) completely backwards: they are given an application that already uses dependency injection and told "Good Luck". But it is really hard to get the benefits from DI if you do not exactly understand what it is and, more importantly, why you want to use it. Let's change that.
In this session, you will see problems that are caused by tightly-coupled code. You will see how dependency injection can break that coupling. And you will see how loosely-coupled code is ultimately easier to extend and test. Along the way you will see some DI patterns such as constructor injection, and you will get a better understanding of what a DI container does. With these skills in hand, you can use dependency injection to make your own code easier to extend and test.
Diving Deeper into Dependency Injection
You know the basics of dependency injection (DI). Now it's time to take a closer look at how DI patterns and other design patterns can help us use DI effectively. We'll look at implementations and uses for DI patterns including constructor injection, method injection, and property injection. In addition, we'll use other design patterns to add functionality to existing objects and to manage disposable dependencies. We'll leave with several practical ways to improve the functionality and testing of our code.
Get Func-y: Understanding Delegates in C#
Delegates are the gateway to functional programming. So lets understand delegates and how we can change the way we program by using functions as parameters, return values, variables, and properties. In addition, we'll see how the built-in delegate types (Func and Action) are waiting to make our lives easier. By looking at code, we'll see how delegates can add elegance, extensibility, and safety to our programming.
IEnumerable, ISaveable, IDontGetIt: Understanding C# Interfaces
You want code that is easy to maintain, extend, and test. C# interfaces are here to help. In this session, you will learn we to use interfaces effectively in your code, starting at the beginning ("What are interfaces?") and then exploring why and when to use them. Along the way you'll learn how to use existing interfaces, implement your own interfaces, and also use interfaces for unit testing and dependency injection. The result is code that is easier to maintain, extend, and test.
I'll Get Back to You: Task, Await, and Asynchronous Methods in C#
There's a lot of confusion about async/await, Task/TPL, and asynchronous and parallel programming in general. So let's start with the basics and look at how we can consume asynchronous methods using Task and then see how the "await" operator can makes things easier for us. Along the way, we’ll look at continuations, cancellation, and exception handling.
Learn to Love Lambdas in C# (and LINQ, Too!)
Lambda expressions in C# can be confusing the first time you walk up to them. But once you get to know them, you’ll see that they are a great addition to your toolbox. Used properly, they can add elegance and simplicity to your code. And some .NET constructs (such as LINQ) lend themselves to lambda expressions. In addition, lambdas let us scope our variables more appropriately with captured variables. We’ll take a look at how lambda expressions work and see them in action. We’ll also see how LINQ can help us move from imperative programming to declarative programming (a gateway to functional-style programming).
Practical Reflection in C#
Reflection is an extremely powerful feature of .NET. But there is a big difference between what we can do and what we should do. Several of these features are useful to the everyday developer. We'll take a quick look at what reflection is capable of and then narrow our focus to practical uses, such as making runtime decisions for features and functionality -- all while balancing flexibility, safety, and performance.
Test-Driven Development in the Real World
Are you tired of trivial TDD examples like FizzBuzz? I am. So let's look at a real-world problem to see how Test-Driven Development (TDD) helps us think is small pieces, build provable code, and reduce the amount of unneeded code that creeps into our applications. In the real world, we have to deal with services, libraries, and dependencies. And we have to deal with strange bugs that crop up. In this session, we'll go beyond the simple examples and learn how to break down complexity, isolate dependencies with mocking, and capture expected exceptions.
Unit Testing Makes Me Faster: Convincing Your Boss, Your Co-Workers, and Yourself
Bosses hate unit testing. They see it as code that doesn't contribute to the final product. And maybe you see testing that way, too. But here's the truth: unit testing makes us faster. We'll look at specific examples of how unit tests save time in the development process by letting us code more confidently, catch bugs earlier, and minimize manual testing. With this in hand, we can show our boss (and ourselves) how unit testing makes us faster.
Asynchronous and Parallel Programming in C# [Workshop]
Asynchronous programming is a critical skill to take full advantage of today's multi-core systems. But async programming brings its own set of issues. In this workshop, we'll work through some of those issues and get comfortable using parts of the .NET Task Parallel Library (TPL).
We'll start by calling asynchronous methods using the Task Asynchronous Pattern (TAP), including how to handle exceptions and cancellation. With this in hand, we'll look at creating our own asynchronous methods and methods that use asynchronous libraries. Along the way, we'll see how to avoid deadlocks, how to isolate our code for easier async, and why it's important to stay away from "async void".
In addition, we'll look at some patterns for running code in parallel, including using Parallel.ForEachAsync, channels, and other techniques. We'll see pros and cons so that we can use the right pattern for a particular problem.
Throughout the day, we'll go hands-on with lab exercises to put these skills into practice.
Objectives
o Use asynchronous methods with Task and await
o Create asynchronous methods and libraries
o Avoid deadlocks and other pitfalls
o Understand different parallel programming techniques
Pre-Requisites
Basic understanding of C# and object-oriented programming (classes, inheritance, methods, and properties). No prior experience with asynchronous programming is necessary; we'll take care of that as we go.
Leveling Up: Dependency Injection in C# [Workshop]
Loosely coupled code is easier to maintain, extend, and test. Dependency Injection (DI) help us get there. In this workshop, we'll see how interfaces can add "seams" to our code that makes it more flexible and maintainable. From there, we'll dig into loose coupling with Dependency Injection. DI doesn't have to be complicated. With just a few simple changes to our constructors or properties, we can have code that is easy to extend and test.
After laying a good foundation, we'll take a closer look by diving into various DI patterns (such as constructor injection and property injection) as well as other patterns that help us handle interception and optional dependencies. Along the way, we'll see how DI helps us adhere to the SOLID principles in our code. We'll also we'll look at common stumbling blocks like dealing with constructor over-injection, managing static dependencies, and handling disposable dependencies.
Throughout the day, we'll go hands-on with labs to give you a chance to put the concepts into action.
If you're a C# developer who wants to get better with concepts like abstraction, loose coupling, extensibility, and unit testing, then this is the workshop for you.
Leveling Up: Unit Testing with C# [Workshop]
Unit testing can make you a faster developer. Good tests let us move forward more confidently, give us instant feedback when checking regression, and help us pinpoint bugs when things go wrong. In this workshop, we'll look at the qualities of good tests, including isolation, repeatability, runnability, and more. And we'll look at specific techniques that make our tests easy to ready, easy to write, and easy to run.
We'll go hands-on with TDD (Test-Driven Development) to see the red-green-refactor cycle in action. Some code is tricky to test: we'll look at how to test for exceptions and error states, and we'll use a mocking framework to create mocks and stubs. Tools include MSTest and NUnit (for testing) and Moq (for mocking), but the skills easily translate to other frameworks.
Objectives
o Why Unit Test? Getting the actual benefits
o Characteristics of a good unit test and how to implement them (including isolation, repeatability, runnability, and more)
o Basics of TDD
o Parameterizing tests
o Techniques for testing exceptions
o Using a mocking framework to isolate dependencies
Pre-Requisites
Basic understanding of C# and object-oriented programming (classes, inheritance, methods, and properties). In addition, experience with interfaces and other forms of abstraction is very helpful. No prior experience with unit testing is necessary; we'll take care of that as we go.
Understanding Asynchronous Programming in C# [Workshop]
Level: Introductory / Intermediate
Asynchronous code is everywhere. In our C# code, we "await" method calls to services and databases; and more and more packages that we use every day have asynchronous methods. But do you really understand what this does?
Understanding is critical. When done correctly, we can make our applications more responsive, faster, and reliable. When done incorrectly, we can block threads or even hang the application entirely.
In this 4-hour workshop, we'll start at the beginning to see how "await" relates to "Task”. We'll do this by calling an asynchronous method, getting a result, and handling errors that come up. We will create our own "awaitable" methods to see how Task and return types work together. With our own methods, we'll also better understand why we may (or may not) care about getting back to the original calling thread. We'll also cover some dangers, such as using "async void" or misusing ".Result". Finally, we'll use Task to run multiple operations in parallel to make things faster. With all of these skills, we can write more effective asynchronous code.
For this workshop, it is assumed that you have experience with C#, but no specific asynchronous programming experience is needed. To run the samples code, you will need .NET 6.0 installed. Jeremy will be using Visual Studio 2022, but the code samples will run using Visual Studio Code or the editor of your choice.
Jeremy Clark
Developer Betterer
Vancouver, Washington, United States
Links
Actions
Please note that Sessionize is not responsible for the accuracy or validity of the data provided by speakers. If you suspect this profile to be fake or spam, please let us know.
Jump to top