Dependency Injection 

and 

Events



"I want to register to a plain old .NET event of a dependency that is supplied via constructor injection."

Constructor Injection

public interface IDependency
{
    event EventHandler ItHappened;
}
public class NeedyClass
{
    private readonly IDependency dependency;
 
    public NeedyClass(IDependency dependency)
    {
        if (dependency == null)
            throw new ArgumentNullException("dependency");
 
        this.dependency = dependency;
        this.dependency.ItHappened += this.OnItHappened;
    }
 
    private void OnItHappened(object sender, EventArgs e)
    {
        // Handle event here
    }
} 




What's wrong with this?

What's wrong?




  • Behaviour in the constructor
  • Dependency is never called
  • No dispose

Third-party Connect

public class NeedyClass
{
    public void DoSomethingInteresting()
    {
        // Handle event here
    }
}
// Third party:
var nc = new NeedyClass();
dependency.ItHappened += (s, e) => nc.DoSomethingInteresting(); 
  • Much simpler
  • NeedyClass doesn't know about dependency
  • Dependency doesn't know about NeedyClass




Problems?

Problems




  • Subscription
    • Remember to subscribe
  • Unsubscription
    • Hold on to that event
    • Remember to unsubscribe


Basically: more fragile

Reactive Extensions

public interface IDependency : IObservable { }
public class NeedyClass : IObserver, IDisposable
{
    private readonly IDisposable subscription;
 
    public NeedyClass(IObservable dependency)
    {
        if (dependency == null)
            throw new ArgumentNullException("dependency");
 
        this.subscription = dependency.Subscribe(this);
    }
    public void OnCompleted() { } 
    public void OnError(Exception error) { } 
    public void OnNext(Unit value)
    {
        // Handle event here
    } 
    public void Dispose()
    {
        this.subscription.Dispose();
    }
} 

Pros

  • No more IDependency
  • Real objects

Cons

  • More complicated
  • Depends on IObservable, but holds on to IDisposable
  • Still doing work in the constructor

Invert all the things!



Made with Slides.com