I’m doing a lot of analysis work across a huge set of .csproj files to figure out some overall statistics. For example, what’s the target framework version for all of the projects?

PowerShell to the rescue! All the .csproj files are XML, so we can get the whole set of target frameworks for a set of repositories cloned under a common top-level folder with a single command pipeline.

The output of that will look something like…

Count Name                      Group
----- ----                      -----
  698 v4.5                      {v4.5, v4.5, v4.5, v4.5...}
   42 v3.5                      {v3.5, v3.5, v3.5, v3.5...}
  160 v4.0                      {v4.0, v4.0, v4.0, v4.0...}
    6 v4.5.1                    {v4.5.1, v4.5.1, v4.5.1, v4.5.1...}
    3 v2.0                      {v2.0, v2.0, v2.0}
    2 v4.5.2                    {v4.5.2, v4.5.2}
    3 v4.0.1                    {v4.0.1, v4.0.1, v4.0.1}

autofac, dotnet comments edit

The State of Autofac

Autofac is a pretty popular inversion of control container for .NET. Core Autofac is approaching 10 million NuGet downloads. There are over 20 extension packages that are part of the GitHub Autofac organization supporting everything from .NET Core to MVC/Web API to Service Fabric.

The thing is… the whole project is effectively run by just two people who are not actually full-time developers on Autofac. It’s just me and Alex Meyer-Gleaves doing the best we can to:

  • Answer questions on StackOverflow, Gitter, the mailing list, GitHub issues lists, and other areas people ask for help.
  • Address new and existing issues in core Autofac and all the extension libraries.
  • Make ongoing improvements and enhancements including adding new extension libraries as demand comes up.

All of that happens in the “spare time” between full-time jobs, family obligations, and trying to maintain an otherwise decent work/life balance.

We get a few pull requests, but IoC/DI integration is tricky business. Small changes can introduce pretty big penalties when it comes to app performance. To that end, we probably don’t get quite as many PRs as you might think, and when we do there’s a lot of analysis that has to go into many of them to ensure we’re not inadvertently breaking something.

We Need Help

There’s a lot to maintain and we’re spread thin. We’re looking for people willing to step up and own some of the Autofac extensions and integrations. If we can focus on core Autofac and core extensions we’ll make better headway on things like fixing up the decorator syntax or addressing some of the longer-running issues that aren’t five-minute fixes.

If you become an owner on one of the extensions, you’ll be responsible for:

  • Bug fixes and enhancements: Issues submitted to the extension library’s repository need to be addressed. Determine if the issue is a bug or not, determine if the enhancement request fits with the library or not, etc.
  • API design: Lots of people rely on Autofac and its extensions, you can’t change the signature of methods or introduce breaking changes without a lot of forethought.
  • Requirements determination: Part of the job of an owner is to decide whether a library should support a particular function. You’ll need to make sure fixes and enhancements fit within the bounds of being willing/able to back it with long term support. Is a fix or enhancement worth addressing?
  • Support: Answering questions by actively monitoring autofac tagged questions on StackOverflow, in Gitter, and on the mailing list.
  • Documentation: Changes to the extension or FAQs get documented so future folks can refer to the docs.
  • Examples: There’s an examples repo that shows simple usage of most extensions.

You won’t just be handed a big lump of code and left on your own, but you’ll be considered a primary owner of the extension and you’ll work with Alex and I to bring things forward. It’s a commitment. We’re looking for owners.

If you’re interested, take a look at the list of extension libraries and pick one you think you’d like to take on. Smaller libraries that might be good candidates are Autofac.Extras.Moq, Autofac.Extras.FakeItEasy, Autofac.Mef, and Autofac.Extras.MvvmCross. Feel free to look at others, these are just examples.

Let us know by filing an issue on the repo or tweeting @AutofacIoC. It’ll help if you let us know a little about yourself, any open source work you may be involved in, that sort of thing. It’s not really a job interview, but we are a team so knowing if you’ll be a team fit is valuable.

Not Interested in Owning?

That’s fine, it’s a lot to take on. We’d love your PRs that solve existing issues with a mind toward non-breaking changes. Especially in some of the lesser-used libraries, there’s definitely some TLC needed.

personal comments edit

Xev, my baby princess

On Monday, January 8, 2018, I had to say goodbye to one of my best friends of 15 years: my beautiful baby cat girl, Xev.

From the day she came home, July 2, 2002, she was trouble.

Xev out playing on the balcony

She was very playful. You can see she’s messing with a flower on the balcony. Later, she’d end up hanging from the wall just off the balcony, having been chased there by our cat, Semper, and would eventually fall into the bushes below. (She was just fine. A little scared, but no worse for the wear. And she definitely didn’t learn her lesson.)

She was enough trouble that we couldn’t just let her roam free her first few nights at home. We kept her in the bathroom instead. We made a bed for her in the sink and she loved it.

Xev has a bed in the sink

I think keeping her in the bathroom sort of affected her long-term. She loved the bathroom. If you were in there, she needed to be in there. She’d wrap string around the base of the toilet, she’d drink out of the sink… even after we moved and she was much older, she’d still get in the sink to sleep or play.

Xev still has a bed in the sink

There are a lot of bathroom stories to share. She’d come in and climb into your pants while you were… uh… doing your business. You could yell for “Pooping Cat” and she’d come to that. I’ll stop there, you get the idea.

So naughty. Always in exactly the place you needed to get and totally not interested in moving.

Xev sitting in the clothes dryer

Her favorite toys were those foil/mylar balls that made crinkling noises and anything with tassels on it. She didn’t really wrestle or do that thing some cats do where they roll over and kick with their back feet. She was more of a “grab and bite” kind of cat.

Xev with a tinsel streamer

She mellowed out a little with age and loved to sleep in the windowsill or on the floor in that one spot of sun that would come through. She didn’t fight over much, but she’d totally push the other cats out of the way to get there if needed.

Xev in the windowsill

When my daughter, Phoenix, was born, Xev was there from day one to be the watchful mother cat.

Xev with newborn Phoenix

Our other cats were friendly to Phoenix, but they never really played with her or cuddled with her. Xev… Xev was Phoenix’s older cat-sister. They were best buddies.

Xev with six-year-old Phoenix

As you can see, Xev loved being held like a baby and getting her tummy rubbed. She’d purr so loud that if you were watching TV you could barely hear your show.

This past weekend we noticed Xev had basically stopped eating. She looked a bit thin, but she was drinking. We didn’t think much of it because she was always sort of a “free spirit” and did what she wanted when she wanted. However, after a couple of days of not eating, we really noticed how thin she was getting and that she was becoming pretty lethargic.

I took her to the vet to get her checked out and we found she was in the later stages of kidney failure. She had apparently been headed downhill for quite some time and had masked it really, really well. By the time any real symptoms showed it was too late.

Even the doctor noted that she didn’t look 15 at all. I agree, she aged very well. Her coat was beautiful, full, and clean. She smelled clean. She was so active, even up until that last day.

We made the decision to let her go instead of forcing her through painful treatments that may or may not have actually prolonged her life. I wanted her to live a good life without suffering.

She was my catbaby for 15 years and I loved her more than I can say.

Xev, my 15 year old catbaby

Goodnight, Princess Xev. We will miss you forever.

personal comments edit

Each month my six-year-old daughter comes home with a “homework menu” - a page that looks sort of like a bingo card but each square has a homework assignment in it. Of the 25 assignments listed, you get to pick 15 to do.

The assignments cover things like, “Write a list of words with a long ‘i’ sound in them” to “Count to 100 by fives.” First grade stuff, no problem. For the most part, she’s got this covered… as long as she doesn’t get off in the weeds.

The other night we did, “Make a list of ten odd numbers.” Easy enough. They’d been learning odds and evens in class, so this shouldn’t be much work. In fact, she finished in just a few seconds, listing all the way from one to 19 in short order.

To help cement the pattern in her mind, I thought I’d show her how all the odd numbers end in 1, 3, 5, 7, or 9. I wrote the numbers in a little table like this so the pattern would be easy to see:

1    11    21    31
3    13    23    33
5    15    25    35
7    17    27    37
9    19    29    39

She got pretty excited about that, then asked the question that took us off the rails.

Phoenix: Daddy, why are they called “odd” and “even” numbers?

Travis: Go grab me like six alphabet blocks from your room and I’ll show you.

She ran to her room, grabbed the blocks, and returned with them bundled in the front of her shirt. She dumped the whole shirt load squarely on my nuts.

Travis (recovering): OK, you know odd numbers, do you know the even ones?

Phoenix: 2, 4, 6, 8, 10.

Travis: Good. Here’s two blocks. [I hold up two blocks.] Is two even or odd?

Phoenix: Even.

Travis: Right. If I split that into two even piles there aren’t any left over. [I put one block in each hand and hold them apart from each other.] See that? Two even piles. Now here’s three blocks. [I hold up three blocks in one hand.] Is three even or odd?

Phoenix: Odd.

Travis: Correct again. If I split that into two even piles… [I put one block in each hand and hold them apart from each other, leaving the remaining block on the arm of the chair.] …then we have an odd man out. That block on the chair is extra. Odd numbers leave an odd man out. Let’s try with four. Is four even or odd?

Phoenix: Even.

Travis: OK, and when I split them [I held two blocks in each hand] I have two even piles. Is five even or odd?

Phoenix: Odd.

Travis: Yup, and when I split them [I hold two blocks in each hand and leave the fifth on the arm of the chair] I have that odd man out. That’s why they’re “even” and “odd.” If it’s an even number, I get even piles when I split it in half. If it’s an odd number, I get an odd man out. Even number - even piles. Odd number - odd man out.

Phoenix: Oh, OK!

Travis: So, let’s review. [I hold up four blocks, two in each hand.] Four is an even number, so when I split it I have… [I pulled my hands apart with two in each hand.]…?

Phoenix: Four blocks.

Travis: Well, I do have four blocks, but we were talking about even and odd. Four is even, right? So if I split it in half, I have…?

Phoenix: Two in each hand.

Travis: That’s true, but I have even piles. Even number, even piles. Five is an odd number [I hold up five blocks in my hands] so when I split it in half [I drop one block on the arm of the chair and hold two in each of my hands] I have…? [I look down at the block on the arm of the chair hopefully]

Phoenix: An extra.

Travis: Yep, but it’s odd so we can remember it easier if we think “Odd number has an odd man out.” If it’s even you have…? [I hide the block on the chair and hold two in each hand.]

Phoenix: Equal piles.

Travis: Uh… yeah, but I really want to know you’re hearing me here, so “Even number, even piles.” Not “equal piles,” but actually the literal words, “even piles.” I need you to say, “even piles.” Sooooo…. Four is even, even numbers have…

Phoenix: Four.

Travis (really close to losing my shit): Even numbers, even piles. So, even numbers have…?

Phoenix: Even piles.

Travis: Yes, and odd numbers have…? [I put the extra block back on the arm of the chair.]

Phoenix: Odd piles.

Travis: An odd man out. Odd numbers have an odd man out. Even numbers, even piles. Odd numbers, odd man out. Even numbers…?

Phoenix: Even piles.

Travis: Odd numbers…?

Phoenix: Odd man out.

Travis: HALLELUJAH!

I think this is going to be a thing with homework this year since last night we ran into basically the same thing.

Travis: OK, Phoe, you need to draw a hexagon.

Phoenix: How many sides is that?

Travis: A hexagon has six sides.

Phoenix: So, five?

AAAAAAAAAARRRRRRRGGGGGGGGGGGGGGGGHHHHHHH

architecture, process comments edit

Today I want to talk about something I’ve seen in a few places that just frustrates me to no end: the repeated failed strangler pattern.

To make sure we’re all on the same page: The strangler pattern is when you want to overhaul an existing system and you do so by wrapping it in a facade. You swap out components under the facade from old bits to new bits, eventually strangling the old system and removing the facade so only the new stuff is left. The idea is that doing this over time potentially has lower risk than rewriting an existing system from scratch.

There are a couple of articles on this pattern here:

In general, I think this is a decent pattern. However, I take issue with the implication of this line from the Fowler article (emphasis mine):

They aren’t yet at the point where the old application is strangled - but they’ve delivered valuable functionality to the business that gives the team the credibility to go further. And even if they stop now, they have a huge return on investment - which is more than many cut-over rewrites achieve.

My challenge is around the notion that you can do a partial strangler and that’s an OK - or even good - thing.

My experience directly contradicts this. Let’s take a hypothetical example:

Let’s say you started out a long time ago, in a galaxy far, far away, with a simple string processing engine. It was long before SOAP or REST. It did what it needed to do, you sold it, and you got some customers up and running with it.

String processing engine

So far, so good. SOAP comes along, and XML is pretty awesome, so you decide you want to start moving away from arbitrary string-in, string-out and to something with more formal contracts. Cool! Strangler to the rescue. Except… you do still have some customers that won’t really be able to update right away… you need to leave access to the original string processing engine in place. New folks can take the new interface, though, so that’s good, right?

XML messages wrapping the string processing engine

Turns out the strangler to convert strings to XML wasn’t quite SOAP due to some custom extensions you needed to create to make it work with the string processing engine. You still really want some SOAP wrappers on this thing, though, so you can start decoupling things and iterate faster over individual services/features. Let’s wrap the XML message handling with actual SOAP contracts that are pretty close to but not exactly like the XML messages.

Except… you sold the XML messaging to some customers and they can’t really switch to the slightly modified contracts for the services. And you really haven’t pushed those original string processor customers to upgrade yet because they’re threatening to leave if you create any breakages.

SOAP services wrapping XML messages wrapping the string processing engine

OK, this time for reals - REST is a bit lighter weight and would lend itself better to some of the new prospective clients’ needs. Getting some REST microservice support in there could really get things going, especially since most of the developers you’re hiring now are more versed in REST and that’s the direction your market is going.

(I bet you see where this is going…)

Except… now you have customers on all three previous layers: SOAP, XML messaging, and string messaging. Gotta keep access to all three of those things. No breaking changes! Ever!

REST services wrapping SOAP services wrapping XML messages wrapping the string processing engine

Does that look at all familiar?

Seems like a bit of a design flaw...

This is why I call it “Death Star Architecture.” You’re not finishing the strangler, so instead of getting the benefit of the pattern, you’re just adding layers to your system that all need to be maintained and tested.

Finish your strangler!

Finish your strangler! In the short term it may seem like you’re getting benefits, but long term the unfinished work results in technical debt that will ultimately cause your destruction.