November 21

Talking about .NET Testing using NCrunch on the Azure & DevOps Podcast

Have you heard of the Azure & DevOps Podcast?

No? Well let me tell you about it. The Azure & DevOps Podcast is hosted by Jeffrey Palermo of Clear Measure. The stated intent of the podcast is to help you ship software more quickly and more reliably.

Jeffrey was kind enough to have me on his podcast to talk about ".NET Testing using NCrunch". If you'll recall, I put together a lightning talk, Supercharge Your .NET Testing with NCrunch, earlier this year over NCrunch. I like NCrunch and you should too. It will help decrease the amount of time you spend in the write code, execute unit tests, and refactor loop. With AI intruding into the development process and a solid testing strategy, it will help you decrease the amount of time spent to evaluate whether or not changes made by various AI agents is indeed correct.

Anyway, if you'd like to know more, check out the podcast!

Category: .NET, C#, Talks, Tools | Comments Off on Talking about .NET Testing using NCrunch on the Azure & DevOps Podcast
July 26

Combined Paging

The CodeGorilla combines widgets created in code and widgets loaded from a database and then pages the results.

What am I doing?

I came across an interesting requirement the other day. I'm sure we're all familiar with paging. Usually you use it with a database with a large amount of rows in a result set. The code to do that with LINQ is pretty straightforward. In this particular case we are working with widgets.

var offset = (page - 1) * pageSize;
var results = await dbContext.Widgets.Skip(offset).Take(pageSize).ToArrayAsync();

As you can see, there are 2 variables/parameters.

Name Description
page specifies the requested page of results to return (it's also 1-based in this case)
pageSize specifies the maximum number of widgets to return for each page
  • Since we are using the skip/take approach to paging, I'll calculate the offset (the number of widgets to skip over to get to the first widget in the requested page).
  • Once the offset is calculated, run the query and .Skip() and .Take() my way to return the page of widgets I need.

That's pretty clear to do, but what happens when I need to combine 2 sources of Widgets in a paged result set?

The Requirements

Static Widgets Retrieval

  • Retrieve the static widgets for the requested page using a black-box method (GetStaticWidgets).
  • The static items should be paged according to the current page and page size.

    Database Widgets Retrieval

  • Retrieve the database widgets for the requested page using a black-box method (GetDbWidgets).
  • The database widgets should be paged according to the current page and page size, but only after static widgets are considered.

    Paging Logic

  • If static widgets are available for the requested page, fill the page with as many static widgets as possible.
  • If the number of static widgets is less than the page size, fill the remainder of the page with database widgets.
  • If there are no static widgets for the requested page, fill the page entirely with database widgets.
  • If the requested page exceeds the total number of available widgets, return an empty result.

    Result Construction

  • The result must be a concatenation of the static widgets (if any) and the database widgets (if any) for the requested page.
  • The order of widgets must be preserved: static widgets first, then database widgets.

The Code

    public void CombinedPaging_ReturnsExpectedItems(int page = 1, int pageSize = 5, int staticItemCount = 5, int dbItemCount = 5, string[]? expected = null)
    {
        // Calculate the offset for the requested page
        var requestedOffset = (page - 1) * pageSize;
        var dbOffset = requestedOffset;
        var dbTake = pageSize;

        // Get all static widgets (static items)
        var staticWidgets = GetStaticWidgets(staticItemCount);
        var staticWidgetsCount = staticWidgets.Length;
        // Page the static widgets for the current page
        staticWidgets = staticWidgets.Skip(requestedOffset).Take(pageSize).ToArray();

        // If there are any static widgets, determine how many db widgets to fetch
        if (staticWidgetsCount > 0)
        {
            // Calculate the offset for db widgets, accounting for static widgets
            dbOffset = int.Max(0, requestedOffset - staticWidgetsCount);
            if (requestedOffset < staticWidgetsCount)
            {
                // If static widgets fill part of the page, only take the remainder from db
                dbTake = int.Max(0, pageSize - staticWidgets.Length);
            }
            else
            {
                // If static widgets are exhausted, take a full page from db
                staticWidgets = [];
                dbTake = pageSize;
            }
        }

        // Get the db widgets for the calculated offset and take
        var dbItems = GetDbWidgets(dbItemCount, dbOffset, dbTake);

        // Combine static and db widgets for the final result (static first, then db)
        var actual = staticWidgets.Concat(dbItems);

        // Assert that the actual result matches the expected result
        actual.ShouldBe(expected);
    }

The Repository

...and that's how it got done (basically). If you'd like to get a copy of this code, you can get it from my GitHub Repository.

Why would you do this?

For starters, it's what was asked for in the work item. Second, when I was getting started in developing software that used databases, best practice was that you pull back only what you need. No more, no less. That's what this code does. The code that generates the static widgets is going to execute everytime this code is run because the number of static widgets determines the number of widgets I need to pull from the databse.

Anyway, nothing earth-shattering, but I found it an interesting bit of code to write and I hope you did too. If you have any questions or comments, please let me know!

The CodeGorilla combines widgets created in code and widgets loaded from a database and then pages the results. He's smiling for Garo.

Category: .NET, C#, LINQ | Comments Off on Combined Paging
July 2

Lines, Lies, and Logic: Making Sense of Code Metrics – The Slide Deck

If you were able to make it out to the North Houston .NET User Group meeting on June 19th, thank you for coming. I thought the talk was well received and the information provided was very therapeutic for everyone there.

If you'd like to check out a copy of the slide deck I put together, you can get it by clicking on the image below.

undefined

If you have any suggestions or ideas about what I should talk about next, please let me know.

Category: .NET | Comments Off on Lines, Lies, and Logic: Making Sense of Code Metrics – The Slide Deck
March 26

Seeking Input for My Upcoming Talk on Code Metrics

Howdy!

I'm preparing a talk on code metrics and would love input from the community on what to cover. I'll be presenting this later this year at both the Houston .NET User Group and the North Houston .NET User Group.

Throughout my software engineering career, I’ve encountered many of these metrics, but I’ve rarely seen a single, clear explanation of them all in one place. My goal with this talk is to demystify code metrics—helping software engineers, architects, and engineering managers understand what these metrics are, what insights they provide, and their limitations.

Right now, I’m planning to cover the following metrics:

  • Code Coverage %

  • Cyclomatic Complexity

  • Maintainability Index

  • Lines of Code (LOC)

  • Code Churn

  • Afferent & Efferent Coupling

  • Instability

  • Coupling Between Objects

  • Depth of Inheritance Tree (DIT)

  • Lack of Cohesion in Methods (LCOM)

  • Tight Class Cohesion / Loose Class Cohesion

  • Response for a Class (RFC)

  • Duplication Percentage

  • Defect Density

This is probably more than I can fit into an hour, so I’d love your input:
✅ Which of these metrics should I prioritize?
✅ Are there any important metrics I’ve overlooked?
✅ Have you found specific metrics useful or misleading in your work?

If there’s enough interest, I could explore a deeper dive or a follow-up session on specific metrics. Let me know what you think!

Category: .NET | Comments Off on Seeking Input for My Upcoming Talk on Code Metrics
March 22

Supercharge Your .NET Testing with NCrunch – The Slide Deck

On Thursday, March 20, 2025, I gave a lightning talk at the North Houston .NET User Group meeting in The Woodlands, Texas. If you are interested in the slide deck I put together here's the PowerPoint presentation; Supercharge Your .NET Testing with NCrunch.

The slide deck doesn't really have anything earth shattering. I used it mostly as a guide for what I wanted to cover.

I felt the talk went well. I was hoping for alot of audience participation which I got. Turns out there are a few people who have used NCrunch who were there. It was a good opportunity to compare notes.

TLDR; NCrunch is awesome and you should use it.

If there are any additional questions, let me know and I'll get them answered.

Category: .NET, Tools, unit testing | Comments Off on Supercharge Your .NET Testing with NCrunch – The Slide Deck
March 14

Speaking at the March 2025 North Houston .NET User Group

At the upcoming North Houston .NET User Group meeting (3/20/2025), Tony Cardella, Software Engineer and Software Engineering Capability Lead at BJSS, will be delivering a lightning talk on the topic of NCrunch.

Title: Supercharge Your .NET Testing with NCrunch

Tired of waiting for tests to run? NCrunch is a powerful continuous testing tool for .NET that runs your tests in the background, providing instant feedback, real-time code coverage, and parallel execution to speed up development. In this lightning talk, we’ll explore how NCrunch works, highlight its key features, and see it in action with a quick demo.

More information is available here: https://www.meetup.com/nhdnug/events/305901663/

Hope to see you there!

Category: .NET, BJSS, C#, Tools, unit testing | Comments Off on Speaking at the March 2025 North Houston .NET User Group
December 1

Advent of Code 2024

It's that time of year again. That's right it's Christmas time and that means...Advent of Code!

Why am I doing Advent of Code this year?

  1. I'm trying to learn Python better. This is the perfect excuse.
  2. My employer, BJSS, is a sponsor again this year.

Language + Tech Stack

In previous years, I've done AoC with .NET/C#, but this year I will be using Python. While an IDE is not needed for Python, I've decided to use JetBrains PyCharm. Check it out if you haven't seen it. I'm still learning the shortcuts, which reminds me to print out the shortcuts. I like using unit testing to help verify that my code works and for that I'll be using pytest. I've been using NCrunch as my .NET continuous test runner but I'll have to use something else for Python; pytest-watch.

Source Control

Git/GitHub is my source control of choice. I added a CI/CD pipeline to validate the code once it's been pushed to the master branch.

Workflow

  1. Setup the code for the puzzle of the day (i.e. add the boilerplate code, but try to keep the amount down)
  2. Read the prompt for part 1.
  3. Start writing code to get the example working for part 1.
  4. Once the code is running with the example, run it against the actual input.
  5. Submit the actual output value.
  6. If the answer is incorrect, rework the code and go to step 4.
  7. If the answer is correct, update the expected value for the part 1 test so that it's green.
  8. Read the prompt for part 2.
  9. Start writing code to the example working for part 2.
  10. Once the code is running with the example, run it against the actual input.
  11. Submit the actual output value.
  12. If the answer is incorrect, rework the code and go to step 10.
  13. If the answer is correct, update the expected value for the part 2 test so that it's green.
  14. Commit the puzzle as is to Git.
  15. Refactor the code til it looks presentable to the public and/or resolve any perf issues.
  16. Commit the refactored code to Git.
  17. Done.

Where can I see your progress?

You can see my progress on my GitHub repo.

Category: .NET, Advent of Code, BJSS, C#, Python | Comments Off on Advent of Code 2024
September 21

gRPC + .NET: Lessons from the Trenches Retrospective

Now that I've had a chance to slow down a bit let's do some creative writing. Let's talk about the "gRPC + .NET: Lessons from the Trenches" talk I gave at the North Houston .NET User Group. As I said previously, the talk was received well and I was really happy about that.

The inspiration or the idea to talk about gRPC came from the work I was doing at a large oil & gas company located in the Energy Corridor in Houston, Texas. My stint on the project lasted about 20 months.

This was actually the 3rd time I've given the talk. The first time was for an internal BJSS event in April of 2024. The second was at the Houston .NET User Group back in June 2024. The neat thing about taking a talk from scratch all the way through several iterations is how the presentation "feels". You should find potholes as you go and make notes to double back to correct and/or add to them.

The intent with the talk was to answer the following questions:

  • What is gRPC?
  • Can you give some evidence that shows that gRPC out-performs REST API?
  • Have you ever used gRPC on a real project?
  • What were some of the issues/problems you encountered and how did you work around them?
  • When should you use gRPC?
  • When should you NOT use gRPC?

I feel like when I got to the 3rd iteration of the talk I was answering all those questions completely and coherently. Including the benchmarks in this version of the talk was a good addition and I'll credit Daniel Wright, Principal Technologist @ BJSS Houston with the idea for that one.

I was surprised that the audience this time around had more experience with gRPC than I was expecting. This lead to alot of good questions and some leading questions that came up right before I answered them on the next slide. The talk started to take on more of a conversation kind of feel than a lecture.

While I did have fun putting this talk together and giving it, I don't think I'm going to hang up my developers hat yet. I'm sure there is still a project out there that needs my help! Now it's time to find another topic to talk about and then probably re-do the circuit next year.

Category: .NET, BJSS, C#, gRPC | Comments Off on gRPC + .NET: Lessons from the Trenches Retrospective
September 20

gRPC + .NET: Lessons from the Trenches Powerpoint Slide Deck

Hey! If you were one of the people who came out to the September 2024 North Houston .NET User Group meeting tonight...thank you! You all were a great audience and I loved the interaction.

As promised, here is a copy of my Powerpoint slide deck (gRPC + .NET: Lessons From the Trenches). Feel free to ask questions if you still have any.

Have a suggestion for another talk I should do? Let me know and if there is enough there I can put one together.

Category: .NET, ASP.NET, ASP.NET Core, C#, gRPC | Comments Off on gRPC + .NET: Lessons from the Trenches Powerpoint Slide Deck
September 11

How to Host a gRPC Service With an Azure App Service (as of 9/10/2024 anyway…)

I'm giving a talk on gRPC next week and I wanted to add more content around some gRPC benchmarks. The recent work I was doing for a client with gRPC was hosted in containers and hosted in AWS. This worked well and we had minimal issues once we got it up and running. For the benchmarks I'm looking to run, I just needed to host the gRPC service in an Azure App Service. Now that I found the correct documentation, this is a piece of cake and I'd like to point it out to anybody else who might be looking for this information in the future.

This is the documentation for deploying a gRPC app on an Azure App Service:

I can confirm that this will also work for .NET 8. It was not working for .NET 9 as of 9/11/2024. I'd expect that to get fixed in the near future.

Category: .NET, ASP.NET, ASP.NET Core, Azure, C#, gRPC | Comments Off on How to Host a gRPC Service With an Azure App Service (as of 9/10/2024 anyway…)