Up or down?
I'm a very visual person. I'm thinking of my application as a hierarchy, where the top is the root and the bottom is a leaf.
I'm also under the understanding that, in DI systems, containers are ignorant of their contained objects' responsibilities/functions. Instead, the contained objects know about their context because the context (a dependency) is injected in.
UP: (The non-DI way?)
Should my events be dispatched from the bottom of my hierarchy and bubble upwards to their parents? E.g. a button in my GUI dispatches a CLICKED event, which is caught by a listening container that responds by carrying out the appropriate action.
DOWN: (The DI way?)
Should my events be dispatched from the top of my hierarchy by a parent that its children listen to? E.g. --... ok, i'm having trouble coming up with this. I'm thinking along the lines of a Mediator that dispatches events for contained objects.
'Up' seems natural to me, but since DI has a container being unaware of its contained objects' behavior, I wouldn't want to respond to their events.
I realize it's POSSIBLE to have nearly any part of a system listen to an event, but I want to understand the fundamental relationship between DI participants, so I can structure them properly. I'm assuming people don't usually just scatter events about their program without regard to structural relationships, dependencies, etc.
My question arises from the responsibility placement in a DI system -- it's the injected object's responsibility to make calls on the injector and the injector's reponsibility to provide services to its dependent objects (which inverts the non-DI paradigm -- hence synonyms like "Inversion of Control" and "Dependency Inversion"). This seems to be a very important, fundamental component of DI -- a shifting of responsibilities. I consider calling an object's functions or listening to its events to BOTH be examples of depending on another object. When an object defines its own behavior based on another object, I call that a dependency because one object KNOWS of the other and also KNOWS what the other does. It has defined itself within the context of the other object. As I understand, DI is set up so that the injected object is dependent on the injector, so it should be the injected object's responsiblity to know all about the injector. And it should NOT be the injector's responsiblity to know about the injected object. So, for the injector to be listening to events on the CONTAINED injected object seems to me like like a misplacement of responsibilities because that means it knows something about its contents.
Please tell me if and how this is wrong.
Dependency Injection and the role assignments within the Observer Pattern are orthogonal concerns. An object may play the role of the observer or observed and simultaneously be either the composing object, the composed object, both, or neither.
Consider a typical example where a button is composed by a control. When the button is clicked, it raises a Clicked event which is responded to by the containing control. In this case the observing object is composing the observed object.
Now consider a screen which composes a number of controls. The screen may raise a Closing event which allows the composed controls to perform their own cleanup work before the entire screen is closed. In this case, the observed object is composing the observers.
Now consider a screen which composes a button and a label. When the button is clicked, the label's Clear() method is called. In this case, neither observer nor observed composes the other, but both are composed by the screen object.
Now consider a screen which raises a Closing event which it itself subscribes to (perhaps ensuring itself to be the final event handler that is registered). When it raises a Closing event, allowing any observers to first perform any actions they might need, it then handles its own event. In this case, the observer is the observed.
Dependency injection concerns how an object obtains its dependencies. The dependency injected into a given object may contain an event the object wants to subscribe to, or the dependency may subscribe to the object it is being injected to. How two objects interact after one is injected into another doesn't really have anything to do with dependency injection.
Concerning your clarification section, I believe I understand the source of your confusion. Traditionally, an object creates its own dependencies. Dependency injection inverts the responsibility of obtaining these dependencies by moving the knowledge of how the dependency is obtained outside of the object. Dependency injection doesn't invert dependency relationships however. You may be confusing Dependency Injection with the Dependency Inversion Principle. The Dependency Inversion Principle does reverse the dependency relationship between "high-level" and "low-level" objects, but dependency injection is only concerned with how dependencies are supplied to a given object. Therefore, use of dependency injection doesn't change how objects normally interact with one another. If prior to using dependency injection object B subscribed to events raised by object A (or vice versa), introducing dependency injection will not change this.
In my experience events will start at the lower level and go up, so, your tire hits a pothole, which will vibrate the car, when the tire was injected into the car class.
But, you need to make certain that each part is able to handle the events.
If the car goes faster, the tire will spin faster, but that is not due to an event, but due to calling a function on the tire to have it achieve a certain speed.
I am seeing it as going up, but you didn't specify how you are determining the direction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With