For patterns (observer pattern, publish/subscribe, visitor pattern) where there is a single entity talking to or dealing with multiple entities the communication has what i call it language problem.
There is something similar i had answered which i recommend you to read Observer pattern; knowing *what* changed?
Basically, if you only give single argument or no arguments which means events are triggered and received as you want but they don't quite convey much. It works fine for many trivial example. On the other side if you keep too much information diverse for each module - then definitely you are creating something (as you call it a container) is only a dumping bags. Even for a moment if we keep encapsulation violation arguments away for a moment, dumping bags are not good. For the first part, if you have one more customer and if the container gets one more information is added all other customers now will have to ignore one more field (and recompile themselves)
Part of the problem really is, that while we typically generalize the observers (i.e. different concrete objects as observer and implement
notify() method) but it is equally important that the
notification that needs to be given itself is a matter of abstraction. We must ask - what should i notify? and even more what must i not notify?
Take a real world notifiers to understand this:
1. First of that class is broadcast type messages
* a notification at airport notifies about: arrived departed flights and their times.
* a stock market bill board notifies about: updates on various stocks
The first thing to understand that what gets notified is far more stable and very easily understandable, and hence, attaching any number receiver will not ever create a problem. The metadata is well defined and even if it has to change, it is likely that most observer will get benefited from it.
So really speaking language problem doesn't exists in broadcast type notifications.
2. The multicast or unicast scenario where there messages specific to obsever
Any typical newsletter or rss feed or email are rather personal, there is too and from fields that get the message to places. Here the message can be anything - so for all practical purposes, the message transmission doesn't typically have any single format that can hold all information - this is another extreme where to which a container can evolve to. As in the cases of emails for example, the metadata is again standardized but much meaningful information is in the body and it is upto the end observer/reader to interpret this. the language problem does exists here but channels (in our case the API which carries information) must be freed from interpreting this. Let the source somehow create a blob of information and let the observer know what to do with the blob.
So in essence, what you really need to do is to model the notification - what is truly the message content which needs to be black-boxed. the essence of the answer i gave in above link is that you may create a sort of generic name-value pairs or any general encoding of messages and pass on. It can even be something like
void* of C. But that exercise is must. On the other hand, find what is the metadata (such as source, timestamps, etc.). These fields can be visible to all message readers.
One last thing to note is, be critical to what is the responsibility of the source/publisher and what is not avoid customizations, extensions to the definition or role of publisher for specific customers. This is the single most source of digression in most such cases. Avoid till you come to a point of loosing salary! :)
Doing all this will force you to put more effort but save you from the technical debt of evolving into a huge (depending on your scale) garbage bag type container and most people cannot figure out why these things are there.