I disagree with "The only true solution"... Copy all the list items to another list, that's not appropriate for all our lists, as we have selected each list to closely match it's use to the OTB functionality.
We created a simple global Event Receiver that will send the email when AssignedTo has changed. You could easily scope this to specific lists or list types if you wanted to.
This worked for us because it is what all of our users who have migrated over from confluence are expecting in all lists. Workflows and alerts added too much management overhead for us to worry about.
Note: do not use the Changing event in case it fails, you choose use the item changed event.