Inversion Of Control & Dependency Injection Break Apart The Dependencies Oren Eini Senior Developer We! Consulting Group
Who wants to try to move that?
What can we do about it?
Who am I and what I do? Senior Developer at We! Mostly dealing with complex business applications 100% of current projects using IoC Blogger - ~95,000 visits / month – Object Relational Mapping – Inversion Of Control – Model View Controller architectures for the web – Various Development topics
What it is – Architecture? Decreased Coupling Greater Flexibility Separation of Concerns Interface Driven Design Dependency Management (via Dependency Injection or Service Lookup) Component Oriented Programming
What is it – Technology? (Very) smart factory Automatic resolving and injection of dependencies
A bit about terminology Container Service / Component Inversion of Control Dependency Injection
What is the problem we are trying to solve? To understand the solution, we need to understand what the problem is…
LET US HAVE A PIZZA…
The Pizza Process
Coupled Pizza Place
Client Code Customer customer = new Customer("Fred"); CoupledPizzaPlace pizzaPlace = new CoupledPizzaPlace(); pizzaPlace.MakeOrder(customer,3);
Coupled Pizza Place Clerk knows about cook Deliveries service knows about clerk Cook knows about clerk Clerk knows about cook Deliveries service knows about clerk Cook knows about clerk
Coupled Pizza Place
Decoupled Pizza Place Just put some interfaces…
Decoupled Client Code Oven oven = new Oven(); MakePizzaCook takePizzaFromOvenCook = new MakePizzaCook(oven); OrdersClerk ordersClerk = new OrdersClerk(takePizzaFromOvenCook); MakeDevliveriesService makeDevliveriesService = new MakeDevliveriesService(ordersClerk); TakePizzaFromOvenCook makePizzaCook = new TakePizzaFromOvenCook(oven, ordersClerk); DecoupledPizzaPlace pizzaPlace = new DecoupledPizzaPlace(takePizzaFromOvenCook, ordersClerk, makeDevliveriesService, makePizzaCook); Customer customer = new Customer("Fred"); pizzaPlace.MakeOrder(customer,3);
Into Factory Method DecoupledPizzaPlace pizzaPlace = DecoupledPizzaPlace.Create(); Customer customer = new Customer("Fred"); pizzaPlace.MakeOrder(customer, 3);
Decoupled Pizza Place
IoC Pizza Place
IoC Client Code IoC.Initialize( new RhinoContainer("Pizza.boo")); Customer customer = new Customer("Fred"); IoCPizzaPlace pizzaPlace = IoC.Resolve (); pizzaPlace.MakeOrder(customer, 3); pizzaPlace.DoWork(); Configuration (later)
Configuring IoC: Using DSL Component("sara", IClerk, OrdersClerk) Component("nissim", ICook, MakePizzaCook) Component("moshe", IMakeDeliveries, MakeDeliveriesService) Component("nir", ICook, TakePizzaFromOvenCook) Component("oven", Oven) Component("pizza", IoCPizzaPlace, Yes, you can do it with XML as well…
IoC.Resolve (); IClerk IMakeDe liveries ICook IClerk Oven Second Cook
Inversion Of Control Container All the services in the application are registered in the container. Single point of access to all the services in the application. Automatically resolves all the dependencies of services registered with the container. Neither the client nor the service are tied to the dependencies.
Benefits of IoC Dependencies are managed for you. Highly focused objects (single responsibility, separation of concerns). Testability. Objects are not coupled directly to environment resources or other unintended implementations
Why not do it myself?
Flexibility… Component("sara", IClerk, OrdersClerk) Component("nissim", ICook, MakePizzaCook) Component("moshe", IMakeDeliveries, MakeDeliveriesService) Component("nir", ICook, TakePizzaFromOvenCook) Component("oven", Oven) Component("pizza", IoCPizzaPlace, TempClerk );
And in the real world… Changing the payment service: PayPal Credit Card Changing the delivery service: UPS FedEx Changing a database Replacing validation rules
Implementations In.Net Castle Windsor Spring.Net Structure Map Object Builder
ADVANCE STUFF: EXPLODING HEADS ZONE
Generic Services Usage: //from database IoC.Resolve >.Get(1337); //from active directory IoC.Resolve >.Get(42);
Configuration Component("users_repository", IRepository of User, ActiveDirectoryRepository) Component("database_repository", IRepository, NHibernateRepository)
Generic Specialization Usage: IoC.Resolve >.Get(5); IoC.Resolve >.Get(15);
A word about decorators Client code… Security Decorator Logging Decorator Caching Decorator Real Reposistory
Configuration Component("logging_users_repository", IRepository of User, LoggingDecorator of User, Component("logging_ database _repository", IRepository, LoggingDecorator, Component("users_repository", IRepository of User, ActiveDirectoryRepository) Component("database_repository", IRepository, NHibernateRepository)
Other uses of Inversion of Control Containers Manage lifetime of services (singleton, transient, per request, etc). Aspect Oriented Programming Decorators
Pros Simpler Architecture Reduced cost of change Encourage best practices Interface driven design and component oriented programming Less work More smarts from the framework
Cons Need to learn Higher level of abstraction Misuse of architecture
Resources Inversion of Control Containers and the Dependency Injection pattern – Martin Fowler Inversion of Control Containers and the Dependency Injection pattern The Dependency Injection Principal - Robert C. Martin The Dependency Injection Principal Inversion of Control and Dependency Injection: Working with Windsor Container – Oren Eini Inversion of Control and Dependency Injection: Working with Windsor Container
Come to meet me at the Architecture & Developers Panels or visit my blog: