Reputation: 6222
When implementing DI, both Mark Seemann, and Misko Hevery say that constructors should be simple, and should only receive dependencies. They should not do anything else. (here and here)
However, often I would like to subscribe to events of the passed in dependencies, but if I do this in the constructor, then the constructor does more than receiving its dependencies, and if I don't, then the object is not fully initialized.
Would it be correct, then, to instantiate those objects which need to subscribe to events in the composition root, hook up their events, and then inject those instantiated objects?
For example:
// Composition root
Panel panel = new Panel();
Button button = new Button();
panel.OnButtonClick += button.Click;
Register<Panel>().AsSingle(panel);
Register<Button>().AsSingle(button);
// Panel Class
private Button _button;
public Panel(Button button)
{
_button = button;
}
void OnButtonClick()
{
// handle button click
}
as opposed to:
//composition root
Register<Panel>().AsSingle(panel);
Register<Button>().AsSingle(button);
// Panel Class
private Button _button;
public Panel(Button button)
{
_button = button;
OnButtonClick += button.Click
}
void OnButtonClick()
{
// handle button click
}
Upvotes: 3
Views: 2275
Reputation: 4643
This answer is primarily opinion based.
I usually does not use DI
to presentation layer, because I assume the best use of DI
is to make a persistence ignorance classes in domain (business) layer. The use of DI
though, is to aim for stateless service
class. It process requests regardless any specified state and is event-less, thus eliminate the need of events inside the service
class.
What you want to create maybe is a control
class, and not service
class, therefore, assigning event is a real problem here. However, I don't think wiring an event violates the constructor rules thing, because it is just assinging event.
Why is it eventless?
It accept request, and process it. If you need something to do like: afterProcess
, beforeProcess
, etc, you can define the specific event in classes, and passing the interfaces as dependency.
What if I need to do event based?
Sometimes you need an event to be passed in some cases. You can do parameter injection using Func
(or adapter in java) instead hooking it in the constructor.
Upvotes: 0
Reputation: 1038780
Yes, wiring up the events in the composition root would be the correct approach here.
Upvotes: 1