dependency injection 2014

Download Dependency Injection 2014

Post on 14-Jul-2015

167 views

Category:

Software

0 download

Embed Size (px)

TRANSCRIPT

  • 12/12/2014

    1

    Steven van Deursen

    cuttingedge.it/blogs/steven

    @dot_net_junkie

    steven@cuttingedge.it

    Dependency Injection

    Dependency injection is a software

    design pattern that implements

    inversion of control and allows a

    program design to follow the

    dependency inversion principle.

    Source:

    en.wikipedia.org/wiki/Dependency_injection

  • 12/12/2014

    2

    Inversion of Control

    Describes the interaction between code and a framework

    IoC does not describe how the interaction takes place.

    Its so common; we dont think about it anymore.

    The SOLID principles

    Single responsibility principle

    Open/closed principle

    Liskov substitution principle

    Interface segregation principle

    Dependency inversion principle

  • 12/12/2014

    3

    Dependency Inversion Principle

    A. High-level modules should not

    depend on low-level modules. Both

    should depend on abstractions.

    B. Abstractions should not depend on

    details. Details should depend on

    abstractions.

    Source:

    en.wikipedia.org/wiki/Dependency_inversion_principle

    Dependency Inversion Principle

    Example: the Copy program

  • 12/12/2014

    4

    Dependency Inversion Principle

    Example: the Copy program

    A. High-level modules should not

    depend on low-level modules. Both

    should depend on abstractions.

    B. Abstractions should not depend on

    details. Details should depend on

    abstractions.

    Dependency Inversion Principle (DIP)

    The problem of class coupling

    Maintainability

    Extendibility

    Reusability

    Testability

    Parallel development

    A. High-level modules should not

    depend on low-level modules. Both

    should depend on abstractions.

    B. Abstractions should not depend on

    details. Details should depend on

    abstractions.

  • 12/12/2014

    5

    static class CameraOperator{public:

    static Snapshot Operate(){

    CameraPosition position = DetermineNextCameraPosition();

    return RaytracingCamera::TakeSnapshot(position);}

    static CameraPosition DetermineNextCameraPosition(){

    time_t currentTime = time(NULL);

    // Assume some complex time dependent calculation.return CameraPosition();

    }};

    DIP Violations

    static class CameraOperator{public:

    static Snapshot Operate(){

    CameraPosition position = DetermineNextCameraPosition();ICamera* camera = ...;return camera->TakeSnapshot(position);

    }

    static CameraPosition DetermineNextCameraPosition(){

    ITimeProvider* timeProvider = ...;time_t currentTime = timeProvider->GetCurrentTime();// Assume some complex time dependent calculation.return CameraPosition();

    }};

    Applying DIP

  • 12/12/2014

    6

    Service Locator

    static class CameraOperator{public:

    static Snapshot Operate(){

    CameraPosition position = DetermineNextCameraPosition();

    ICamera* camera = Locator::Get();return camera->TakeSnapshot(position);delete camera;

    }

    static CameraPosition DetermineNextCameraPosition(){

    ITimeProvider* timeProvider = Locator::Get();time_t currentTime = timeProvider->GetCurrentTime();delete timeProvider;

    // Assume some complex time dependent calculation.return CameraPosition();

    }};

    Service Locator

  • 12/12/2014

    7

    Service Locator

    Advantages

    Easy to grasp

    Easy to get started with in a legacy application

    Service Locator

    Disadvantages

    DIP violation in itself

    Cant work without the Locator

    Context unclear from perspective of the locator

    Hard to test

    No compile-time support

    Dependencies unclear

  • 12/12/2014

    8

    Service Locator is an anti-pattern

    Dependency Injection

  • 12/12/2014

    9

    class CameraOperator{private:

    ITimeProvider* timeProvider;ICamera* camera;

    public:CameraOperator(ITimeProvider* timeProvider, ICamera* camera){

    this->timeProvider = timeProvider;this->camera = camera;

    }

    Snapshot Operate(){

    CameraPosition position = DetermineNextCameraPosition();return this->camera->TakeSnapshot(position);

    }

    CameraPosition DetermineNextCameraPosition(){

    time_t currentTime = this->timeProvider->GetCurrentTime();return CameraPosition();

    }};

    Dependency Injection

    Dependency Injection

    Advantages

    Dependencies clear

    Compile-time support

    Easy to spot SRP violations

    No more dependency with Locator.

  • 12/12/2014

    10

    Dependency Injection

    Disadvantages

    Well get to that

    class MovieScene{public:

    void RecordScene(){

    SystemTimeProvider* timeProvider = new SystemTimeProvider();RaytracingCamera* camera = new RaytracingCamera();CameraOperator* cameraOperator =

    new CameraOperator(timeProvider, camera);MpegFileRecorder* recorder =

    new MpegFileRecorder("c:\\movies\\di_bloopers.mpg");

    while (!wholeSceneRecorded) {Snapshot snapshot = cameraOperator->Operate();recorder->Append(snapshot);

    }

    delete recorder;delete cameraOperator;delete camera;delete timeProvider;

    }};

    Dependency Injection

  • 12/12/2014

    11

    class MovieScene{private:

    ITimeProvider* timeProvider;ICamera* camera;IRecorder* recorder;

    public:MovieScene(ITimeProvider* provider, ICamera* camera, IRecorder* recorder){

    this->timeProvider = provider;this->camera = camera;this->recorder = recorder;

    }

    void RecordScene(){

    CameraOperator* cameraOperator =new CameraOperator(this->timeProvider, this->camera);

    while (!wholeSceneRecorded) {Snapshot snapshot = cameraOperator->Operate();this->recorder->Append(snapshot);

    }

    delete cameraOperator;}

    };

    Dependency Injection

    class MovieScene{private:

    ICameraOperator* cameraOperator;IRecorder* recorder;

    public:MovieScene(ICameraOperator* cameraOperator, IRecorder* recorder){

    this->cameraOperator = cameraOperator;this->recorder = recorder;

    }

    void RecordScene(){

    while (!wholeSceneRecorded) {Snapshot snapshot = this->cameraOperator->Operate();this->recorder->Append(snapshot);

    }}

    };

    Dependency Injection

  • 12/12/2014

    12

    int _tmain(int argc, _TCHAR* argv[]){

    // Composition RootITimeProvider* timeProvider = new SystemTimeProvider();ICamera* camera = new RaytracingCamera(1280, 1024);ICameraOperator* operator =

    new CameraOperator(timeProvider, camera);

    IRecorder* recorder =new MpegFileRecorder("c:\\movies\\di_successStories.mpg");

    MovieScene* movieScene = new MovieScene(cameraOperator, recorder);

    movieScene->RecordScene();

    delete movieScene;delete recorder;delete cameraOperator;delete camera;delete timeProvider;

    return 0;};

    Composition Root

    ITimeProvider* g_timeProvider = new SystemTimeProvider();

    int _tmain(int argc, _TCHAR* argv[]){

    while (true) // Simulate requests{

    Request* request = CreateScene(new WireframeCamera(375, 300), new ScreenViewer());

    MovieScene* scene = request->Root;scene->RecordScene();delete request;

    }

    return 0;};

    Request* CreateScene(ICamera* camera, IRecorder* recorder){

    Request* request = new Request();

    request->Root = new MovieScene(request->Add(new CameraOperator(

    g_timeProvider, request->Add(camera))),

    request->Add(recorder));

    return request;};

    Composition Root

  • 12/12/2014

    13

    Composition Root

    Advantages of centralizing creation of object graphs

    Not doing so fails DIP

    Easier to reason about concurrency and thread-safety

    Easier to reason about resource management.

    Dependency Injection

    Disadvantages?

    Takes time to master

    Not easy to apply in legacy systems

  • 12/12/2014

    14

    Books!

    Mark Seemann

    Roy Osherove

    Jeff Langr

    Robert C. Martin

    Steven van Deursen

    cuttingedge.it/blogs/steven

    @dot_net_junkie

    steven@cuttingedge.it