27
Dependency Injection and Autofac By: Keith Schreiner & Jeff Benson

Dependency Injection and Autofac

Embed Size (px)

DESCRIPTION

This presentation talks about the Dependency Injection design principle, providing an overview of the pattern and its benefits while showing examples on how to apply it using Autofac, a specific dependency injection tool for .NET development. Autofac: http://code.google.com/p/autofac/ A book on DI: http://www.manning.com/seemann/

Citation preview

Page 1: Dependency Injection and Autofac

Dependency Injection and Autofac

By: Keith Schreiner & Jeff Benson

Page 2: Dependency Injection and Autofac

Goals

1) Provide basic info about DI.2) Get you excited to use DI.3) Get you to recommend using a DI tool (like

Autofac) on your next project.

Page 3: Dependency Injection and Autofac

Why?

DI enables loose coupling, and loose coupling makes code more maintainable.

Great for medium or big applications that need to be maintained.

DI can change the way you write software. (Good)Instead of bottom-up, DI allows for top-down.

(DB to UI) (UI to DB)

Page 4: Dependency Injection and Autofac

Definition of Dependency Injection

• A set of object-oriented software design principles & patterns that enable us to develop loosely coupled code, by passing or setting the dependencies of a program.

• Instead of components having to request dependencies, they are given (injected) into the component.

• (Sounds complex, but really isn’t.)

Page 5: Dependency Injection and Autofac

Explain Dependency Injection to a 5-year old

When you go and get things out of the refrigerator for yourself, you can cause problems.

You might leave the door open, you might get something Mommy or Daddy doesn't want you to have. You might even be looking for something we don't even have, or which has expired.

What you should be doing is stating a need, "I need something to drink with lunch," and then we will make sure you have something when you sit down to eat.

From John Munsch on Stack Overflow

Page 6: Dependency Injection and Autofac

DI is a set of Design Patterns & Principles

Making code more maintainable through loose coupling is the core motivation behind many classic design patterns (dating back to 1995 and the Gang of Four):

Program to an interface, not an implementation

Page 7: Dependency Injection and Autofac

Property Injectionpublic partial class SomeClass{ private ISomeInterface dependency; public ISomeInterface Dependency { get { if (this.dependency == null) this.Dependency = new DefaultSome(); return this.dependency; } set { if (value == null) throw new ArgumentNullException("value"); if (this.dependency != null) throw new InvalidOperationException(); this.dependency = value; } } public string DoSomething(string message) { return this.Dependency.DoStuff(message); }

When a dependency is optional. + Simple to understand. - But limited in its use. - Not simple to implement robustly.

Page 8: Dependency Injection and Autofac

SOLID & DIS Single Responsibility Principle

• An object should have only a single responsibility.

OOpen/Closed Principle• Software entities should be open for extension, but closed for

modification.

LLiskov Substitution Principle• Objects in a program should be replaceable with instances of their

subtypes without altering the correctness of that program.

IInterface Segregation Principle• Many client specific interfaces are better than one general purpose

interface.

DDependency Inversion Principle• One should depend on abstractions; do not depend upon

concretions.

Page 9: Dependency Injection and Autofac

Benefits of DI

• Late Binding• Extensibility• Parallel Development• Maintainability• Testability• Code Structure

– Interface Driven Development– All dependencies registered in one spot– Never have to write code to “new-up” objects.

Page 10: Dependency Injection and Autofac

Negatives of DI

• Learning curve.

• Constructor code may look more complicated.

• Code may seem “magical” for developers who do not know DI.

• Is over-kill for very small projects.

• Makes classes harder to re-use outside of a DI app.

Page 11: Dependency Injection and Autofac

DI Myths

• Not just relevant for late binding.

• Not just relevant for unit testing.

• Is not just a Service Locator.

Page 12: Dependency Injection and Autofac

DI or Inversion of Control

Sometimes DI and IoC are interchanged.

IoC = Inversion of ControlIoC = A framework controls program flow.

IoC includes DI.

Page 13: Dependency Injection and Autofac

Example

A “Hello World” or any small example will do a horrible job of showing off DI. But here it is…

[Shipping with Weather]1. Write some Interfaces2. Implement some classes. Class Foo : IFoo3. Create a class to load the modules4. In this loading-class, register and configure your classes5. In the startup of your program, register this loading-class

Page 14: Dependency Injection and Autofac

DI Dimensions (Ideas)1) Object Composition2) Object Interception3) Object Lifetime Management

a) InstancePerDependency

b) SingleInstance

c) InstancePerLifetimeScoped) InstancePerMatchingLifetimeScope

Page 15: Dependency Injection and Autofac

.NET DI Containers

There are many good choices (feel free to try others):• Castle Windsor (Popular, but big. Good choice)• Structure Map (Oldest [2004] .net DI container, popular)• Spring.NET (port from Java, big learning curve)• Unity (From Microsoft’s P&P team, solid but different)• Ninject (Good, simple to use)• Autofac (Most recent, based on C# 3, gaining popularity)

Plus about 10 other not-as-popular ones.

Page 16: Dependency Injection and Autofac

Autofac

• Get it: http://autofac.org or NuGet.

• What you get: a zip with binaries.

• Platforms: .NET 3.5 SP1, .NET 4, Silverlight 3 & 4, Windows Phone 7.

• Cost? Free. It is open source.

• Help? http://autofac.org or StackOverflow

• ReSharper also really helps speed-up dev.

Page 17: Dependency Injection and Autofac

Autofac Integration

Autofac has additional packages for integration:• ASP.NET WebForms• ASP.NET MVC3• WCF (Windows Communication Foundation)• And others

Page 18: Dependency Injection and Autofac

Using Autofac

1) Develop your code using DI-friendly patterns2) Configure Autofac

1) Create a ContainerBuilder2) Add configuration.

• Tell the ContainerBuilder your objects, and interfaces, and lifetimes, etc.

3) Create a Container (from the ContainerBuilder)4) Use the Container to resolve components (objects).

Page 19: Dependency Injection and Autofac

Configuration

• Code• Auto (using an assembly)• XML

Recommend: Use Package config Autofac.Module

Page 20: Dependency Injection and Autofac

Registering Dependencies in Autofac

1) Type, lambda expression, specific instance, or auto-registerbuilder.RegisterType<TaskController>();

builder.Register(c => new TaskController(c.Resolve<ITaskRepository>())

);

builder.RegisterInstance(new TaskController());

builder.RegisterAssemblyTypes(typeof(IPresenter).Assembly) .Where(t => t.IsAssignableTo<IPresenter>()) .OnActivating(e => ((IPresenter)e.Instance).SetupView());

Page 21: Dependency Injection and Autofac

Lifetime Options

1. InstancePerDependency2. InstancePerLifetimeScope3. InstancePerMatchingLifetimeScope4. SingleInstance

Page 22: Dependency Injection and Autofac

Applying Autofac

• Let’s see how we can use DI and Autofac on a big project.

• First, how one might normally create the project without using DI.

• Second, how to create it with DI.

Page 23: Dependency Injection and Autofac

Common 3-tier App without DI

• Not “wrong,” but not an inherent guarantee of loose coupling

• Build Data, then BI, then UI. (bottom-up)

• The layers really are tightly coupled together, like the domain entities from the data layer.

• Hard to test.

• Config file dependent.

Page 24: Dependency Injection and Autofac

Advanced Configurationg (for more complex APIs)

Builder.RegisterType<Chicken>().As<IIngredient>(); Builder.RegisterType<Steak>().As<IIngredient>();Last one wins, unless you ask for an array of IIngredient’s.

Builder.RegisterType<Chicken>().Named<IIngredient>(“chicken”); Builder.RegisterType<Steak>().Named<IIngredient>(“steak”);Can also “name” your registrations.

This allows you to do many things when working with multiple components with the same interface, often with lambda expressions.Builder.RegisterType<Meal>().As<IMeal>().WithParameter( (p,c)=>true,(p,c)=>new[] {c.ResolveNamed<IIngredient>(“chicken”), c.ResolveNamed<IIngredient>(“steak”)});

Also, if your constructor has a string, number, enum as a parameter, it is possible to register that string as a component, or pass them in as a NamedParameter.

Page 25: Dependency Injection and Autofac

Summary• Use DI to enable loose coupling and to make code

more maintainable.• DI is just a set of good patterns, like programming to

an interface.• Using DI can change the way you code (for the

better) because of the good patterns.• There are several DI tools to choose from and

Autofac is good choice.• Use DI on your next project!

Page 26: Dependency Injection and Autofac

Resources• Autofac.org

• Book: “Dependency Injection in .NET” by Mark Seemann. http://www.manning.com/seemann/

• Podcast with Autofac creator http://www.dotnetrocks.com/default.aspx?showNum=450

• Advanced relationship types with Autofac http://nblumhardt.com/2010/01/the-relationship-zoo/

• Stackoverflow.com

Page 27: Dependency Injection and Autofac