SlideShare a Scribd company logo
http://stackoverflow.com/questions/1638919/how-to-explain-dependency-injection-to-a-5-year-old/1638961#1638961
Dependency Injection, 
the right way 
Thibaud DESODT 
@tsimbalar
This talk 
• What it is about 
– Dependency Injection (DI) patterns 
– Benefits 
– Common pitfalls 
• What it is not about 
– Specific IoC/DI Container implementations 
• Pre-requisites 
– OOP 
– Class-based statically-typed languages 
• Based on examples
Dependency injection - the right way
What ? 
DEPENDENCY INJECTION
Dependency Injection 
Dependency Injection is a set of practices that 
allow to build loosely coupled applications
Dependency Injection 
Dependency Injection is a set of practices that 
allow to build loosely coupled applications 
It’s NOT : 
– A library 
– A framework 
– A tool 
It IS : 
- A way of thinking 
- A way of designing code 
- General guidelines
Dependency Injection 
Dependency Injection is a set of practices that 
allow to build loosely coupled applications 
Small components … 
- Independent 
- Reusable 
- Interchangeable 
… plugged together to 
form a bigger system 
Benefits : 
- Small classes with single 
responsibility 
- Easier maintenance 
- Extensibility 
- Testable
Show me the code ! 
FROM TIGHTLY TO LOOSELY 
COUPLED
Example : Boring Bank™ System 
• Features 
– User can list his 
accounts 
– User can rename his 
accounts 
– User can transfer money 
from an account to the 
other 
• Tech : 
– Web front-end 
– Relational database
Starting from scratch 
public class AccountController : BaseController 
{ 
// GET: Account 
[HttpGet] 
public ActionResult Index() 
{ 
var userId = this.User.AsClaimsPrincipal().UserId(); 
using (var context = new BankingDbContext()) 
{ 
var accounts = context.Accounts 
.Where(a => a.CustomerId == userId) 
.OrderBy(a => a.Title).ToList(); 
return View(accounts); 
} 
} 
[HttpPost] 
public ActionResult TransferPost(int from, int to, decimal amount) 
{ 
var userId = this.User.AsClaimsPrincipal().UserId(); 
using (var context = new BankingDbContext()) 
{ 
var accountFrom = context.Accounts 
.Single(a => a.CustomerId == userId && a.Id == from); 
var accountTo = context.Accounts 
.Single(a => a.CustomerId == userId && a.Id == to); 
accountFrom.Balance -= amount; 
accountTo.Balance += amount; 
context.SaveChanges(); 
return RedirectToAction("Index"); 
} 
} 
data 
business 
presentation
Tightly-coupled code 
• Using another kind of UI ? 
• Using another kind of storage ? 
• Using the business rules somewhere else ?
Separation of Concerns 
• Layered architecture / split assemblies 
– Presentation 
– Business 
– Data-access (Repository) 
• Separated : 
– Persistence Entities 
– Domain Entities 
– View Models
public class AccountController : BaseController 
public Account GetAccountForCustomer(int customerId, int accountId) 
{ 
// GET: Account 
[HttpGet] 
public ActionResult Index() 
{ 
var userId = this.User.AsClaimsPrincipal().UserId(); 
public void Transfer(int userId, int fromAccountId, int toAccountId, decimal amountToTransfer 
var userAccountService = new UserAccountService(); 
var accounts = userAccountService.GetAccountsForCustomer(userId); 
return View(ToViewModel(accounts)); 
} 
[HttpPost] 
public ActionResult TransferPost(int from, int to, decimal amount) 
{ 
var userId = this.User.AsClaimsPrincipal().UserId(); 
var userAccountService = new UserAccountService(); 
userAccountService.Transfer(userId, from, to, amount); 
return RedirectToAction("Index"); 
} 
AccountController.cs (WebPortal) 
UI talks to Business 
{ 
// TODO : validate arguments 
var accountRepository = new AccountRepository(); 
var fromAccount = accountRepository.GetAccountForCustomer(userId, fromAccountId); 
var toAccount = accountRepository.GetAccountForCustomer(userId, toAccountId); 
// TODO : verify that there is enough money 
fromAccount.Balance -= amountToTransfer; 
toAccount.Balance += amountToTransfer; 
accountRepository.Update(fromAccount); 
accountRepository.Update(toAccount); 
} 
UserAccountService.cs (Business) 
Business talks to Data 
{ 
using (var context = new BankingDbContext("BankingDbContext")) 
{ 
var account = context.Accounts 
.Single(a => a.CustomerId == customerId && a.Id == accountId); 
return account; 
} 
} 
public void Update(Account account) 
{ 
using (var context = new BankingDbContext("BankingDbContext")) 
{ 
var accountEf = context.Accounts.Find(account.Id); 
// theoretically, could do "if not changed" 
accountEf.Balance = account.Balance; 
accountEf.Title = account.Title; 
context.SaveChanges(); 
} 
} 
AccountRepository.cs (Data)
That looks fine … but is it ?
anti-pattern : Control Freak 
• Symptoms: 
– Code insists on how the dependencies are built 
– Makes it impossible to use component in isolation 
– Not testable without full stack 
• Easy to spot : new everywhere 
AccountController : BaseController 
Account 
HttpGet] 
ActionResult Index() 
userId = this.User.AsClaimsPrincipal().UserId(); 
userAccountService = new UserAccountService(); 
accounts = userAccountService.GetAccountsForCustomer(userId); 
return View(ToViewModel(accounts)); 
public void Transfer(int userId, int fromAccountId, int toAccountId 
{ 
// TODO : validate arguments 
var accountRepository = new AccountRepository(); 
var fromAccount = accountRepository.GetAccountForCustomer 
var toAccount = accountRepository.GetAccountForCustomer 
// TODO : verify that there is enough money 
fromAccount.Balance -= amountToTransfer; 
toAccount.Balance += amountToTransfer; 
accountRepository.Update(fromAccount); 
accountRepository.Update(toAccount); 
}
Unit tests as a Coupling Detector 
• Unit tests are “just another client” for your 
code 
• If unit tests are hard to write, the code is 
probably too tightly coupled 
-> Let’s make it testable !
Making it testable - Properties 
public class UserAccountService 
{ 
[TestMethod] 
public void RenameAccount_must_UpdateAccountName() 
{ 
public UserAccountService() 
{ 
AccountRepository = new AccountRepository("BankingContext"); 
} 
#region Dependency Management 
public AccountRepository AccountRepository { get; set; } 
#endregion 
Settable property allows 
to “inject” another instance 
// Arrange 
var newName = "someName"; 
var existingAccount = AnAccount(); 
var sut = new UserAccountService(); 
sut.AccountRepository = FAIL FAIL//I want to put a fake here ! 
// Act 
sut.RenameAccount(existingAccount.CustomerId, existingAccount.Id, 
newName); 
// Assert 
// I want to verify what happened .. 
} 
In UserAccountServiceTest.cs , in test project Business.Tests
Programming to an interface 
public class UserAccountService : IUserAccountService 
[TestMethod] 
{ 
public void RenameAccount_must_UpdateAccountName() 
{ 
public UserAccountService() 
{ 
// Arrange 
var newName = "someName"; 
AccountRepository = new AccountRepository("BankingContext"); 
} 
var existingAccount = AnAccount(); 
#region Dependency Management 
var mockRepo = new Mock<IAccountRepository>(); 
mockRepo.Setup(r => r.GetAccountForCustomer(It.IsAny<int>(), It.IsAny<int>())) 
public IAccountRepository AccountRepository { get; set; } 
.Returns(existingAccount); 
var sut = new UserAccountService(); 
sut.AccountRepository = mockRepo.Object; //I want to put a fake here ! 
#endregion Use an interface (or abstract class) instead of concrete class 
// Act 
sut.RenameAccount(existingAccount.CustomerId, existingAccount.Id, newName); 
// Assert 
mockRepo.Verify(r=> r.Update(It.Is<Data.Account>(a=> a.Title == newName))); 
} 
Inject fake instance
pattern : Property Injection 
Expose settable properties to modify dependencies 
Benefits 
• Useful to provide optional extensibility 
• There must be a good “local default” implementation 
Caveats 
• Not very easy to discover point of extension 
• Easy to forget 
• Extra care to avoid NullReferenceExceptions, handle 
thread-safety etc
Making it more explicit - Constructor 
public class UserAccountService : IUserAccountService 
{ 
private readonly IAccountRepository _accountRepository; 
Injection constructor 
used in tests - declare required dependencies as constructor parameters 
public UserAccountService(IAccountRepository accountRepository) 
{ 
public IAccountRepository AccountRepository { get { return _accountRepository; if (accountRepository == null) throw new ArgumentNullException("accountRepository 
_accountRepository = accountRepository; 
} 
public UserAccountService() 
:this(new AccountRepository("BankingContext")) 
{ 
} 
#region Dependency Management 
Default constructor 
used in production code 
[TestMethod] 
public void RenameAccount_must_UpdateAccountName() 
{ 
// Arrange 
var newName = "someName"; 
var existingAccount = AnAccount(); 
var mockRepo = new Mock<IAccountRepository>(); 
mockRepo.Setup(r => r.GetAccountForCustomer(It.IsAny<int>(), It.IsAny<int>())) 
.Returns(existingAccount); 
var sut = new UserAccountService(mockRepo.Object); 
// Act 
sut.RenameAccount(existingAccount.CustomerId, existingAccount.Id, newName); 
// Assert 
mockRepo.Verify(r=> r.Update(It.Is<Data.Account>(a=> a.Title == newName))); 
} 
Inject fake instance
anti-pattern : Bastard Injection 
Enable dependencies for testing, but use hard-code 
implementation in production code 
• Paradox: 
– Lots of efforts to reduce coupling 
– … but forcing a hard-coded value 
• Test-specific code 
• Ambiguity
Cutting the dependency chain 
public class AccountController : BaseController 
{ 
private readonly IUserAccountService _userAccountService; 
public class UserAccountService : IUserAccountService 
Only 1 constructor - dependencies passed as constructor arguments 
{ 
public private AccountController(readonly IAccountRepository IUserAccountService _accountRepository; 
userAccountService) 
{ 
if (userAccountService == null) throw new ArgumentNullException("userAccountService 
_userAccountService = userAccountService; 
} 
public UserAccountService(IAccountRepository accountRepository) 
{ 
if (accountRepository == null) throw new ArgumentNullException("accountRepository 
_accountRepository = accountRepository; 
AccountController (WebPortal) 
} 
UserAccountService.cs (Business)
pattern : Constructor Injection 
Declare required dependencies as constructor 
parameters 
• Declarative 
• Discoverable (Intellisense, Reflection …) 
• Recommended approach in 99.9% of cases 
• Easy to implement 
Need Guard clause because C# does not support non-nullable 
reference types …
Inverted depency
This is great and everything except … 
[InvalidOperationException: An error occurred when trying to create a controller of 'BoringBank.WebPortal.Controllers.AccountController'. Make sure that the controller System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext 
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext
The chicken and the egg 
IAccountRepository repo = new IAccountRepository(); 
• Ideal world: Programming to interfaces 
vs 
• Real world : applications do not work with only 
interfaces 
• Class instances have to be created and assembled 
(=composed) at some point 
• This happens only in one place in an application
pattern : Composition Root 
Composition of classes into a larger system should 
happen only in one place 
• Create one object-graph 
• As late as possible 
• Only part of the code that can reference concrete types 
Where ? 
• Only applications have a Composition Root 
• There is no Composition Root in a class library 
• Extension point depends on the kind of app
ASP.NET MVC Composition Root 
public class AppCompositionRoot : DefaultControllerFactory 
• IControllerFactory 
• Creates a controller instance based on URL 
• DefaultControllerFactory uses default 
constructor on Controller 
• … but it can be changed ! 
{ 
protected override IController GetControllerInstance(RequestContext requestContext 
Type controllerType) 
{ 
// how to compose an AccountController ? 
if (controllerType == typeof(AccountController)) 
{ 
var connectionString = ConfigurationManager 
.ConnectionStrings["BankingDbContext"].ConnectionString; 
var repo = new AccountRepository(connectionString); 
var service = new UserAccountService(repo); 
return new AccountController(service); 
Controller 
composition 
} 
// standard way in MVC to use default strategy 
return base.GetControllerInstance(requestContext, controllerType); 
} 
} 
public class MvcApplication : System.Web.HttpApplication 
{ 
protected void Application_Start() 
{ 
var factory = new AppCompositionRoot(); 
ControllerBuilder.Current.SetControllerFactory(factory); 
In Global.asax 
tell MVC to use our composition root
Pure DI (aka Poor Man’s DI) 
Manual wiring of dependencies 
• Very explicit (no « magic ») 
• Type-safe 
• … but repetitive and boring 
var connectionString = ConfigurationManager 
.ConnectionStrings["BankingDbContext"].ConnectionString; 
var repo = new AccountRepository(connectionString); 
var service = new UserAccountService(repo); 
return new AccountController(service);
And we did that because … ? 
SO WHAT ?
Benefits of full DI-friendly codebase 
• Testability 
• Maintainability 
• Allows parallel work 
• … and more ! 
• Defined in a centralized location
Reusability / Extensibility 
or CLI 
or WPF 
or Web API 
or WCF 
… 
or files 
or NoSQL 
or Azure 
or Http Client 
…
Extensibility 
public class CachedAccountRepository : IAccountRepository 
{ 
private readonly ICache _cache; 
private readonly IAccountRepository _decorated; 
• Decorator Pattern 
public CachedAccountRepository(ICache cache, IAccountRepository decorated) 
{ 
– Very DI-friendly pattern 
var nakedRepo = new AccountRepository(connectionString); 
if (cache == null) throw new ArgumentNullException("cache"); 
if (decorated == null) throw new ArgumentNullException("decorated"); 
_cache = cache; 
_decorated = decorated; 
// decorate the nakedRepository with caching features 
var • Example longCache = : new caching 
DotNetCache(TimeSpan.FromHours(1)); 
var cachedRepo = new CachedAccountRepository(longCache, nakedRepo); 
var service } 
= new UserAccountService(cachedRepo); 
public IReadOnlyList<Account> GetAccountsForCustomer(int userId) 
{ 
var accounts = _cache.GetOrAdd("accounts_" + userId, 
() => _decorated.GetAccountsForCustomer(userId)); 
return accounts; 
} 
Decorator 
delegate to decorated instance
DI CONTAINERS
DI Container – how they work 
• Mapping Abstraction-> Concrete Type 
– Usually initialized on app start 
– Methods like 
Register<IAbstraction,ConcreteType>() 
• Method Resolve<TRequired>() 
• Recursively resolves dependencies reading 
constructor parameters
public class DependencyConfig 
Example - Unity 
{ 
public static void Configure(IUnityContainer container) 
{ 
var connectionString = ConfigurationManager.ConnectionStrings["BankingDbContext" 
public class MvcApplication : System.Web.HttpApplication 
{ 
public class AppCompositionRoot : DefaultControllerFactory 
protected void Application_Start() 
{ 
private readonly IUnityContainer _unityContainer; 
var container = new UnityContainer(); 
DependencyConfig.Configure(container); 
var compositionRoot = new AppCompositionRoot(container); 
ControllerBuilder.Current.SetControllerFactory(compositionRoot 
{ 
In Global.asax 
.ConnectionString; 
container.RegisterType<IAccountRepository, AccountRepository>( 
new InjectionConstructor(connectionString)); 
container.RegisterType<IUserAccountService, UserAccountService>(); 
} 
} 
public AppCompositionRoot(IUnityContainer unityContainer) 
{ 
In DependencyConfig 
if (unityContainer == null) throw new ArgumentNullException("unityContainer 
_unityContainer = unityContainer; 
} 
protected override IController GetControllerInstance(RequestContext requestContext 
controllerType) 
{ 
return (IController) _unityContainer.Resolve(controllerType); 
} 
} 
In CompositionRoot 
Register / Resolve (/ Release)
Aspects of DI 
• Composition 
• Lifetime Management 
• Interception
Interception 
• ~ Dynamic Decorators 
• Cross-cutting concerns 
– Logging 
– Auditing 
– Profiling … 
• AOP-like !
public class TimingBehavior : IInterceptionBehavior 
{ 
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext 
{ 
var stopwatch = new Stopwatch(); 
// Before invoking the method on the original target. 
Debug.WriteLine("> {0}.{1}", input.MethodBase.DeclaringType, input.MethodBase.Name); 
stopwatch.Start(); 
// Invoke the next behavior in the chain. 
var result = getNext()(input, getNext); 
stopwatch.Stop(); 
// After invoking the method on the original target. 
if (result.Exception != null) 
{ 
Debug.WriteLine( 
Call to decorated instance 
"< {0}.{1} failed - after {3} ms", 
input.MethodBase.DeclaringType, input.MethodBase.Name, result.Exception.GetType(), 
stopwatch.ElapsedMilliseconds); 
} 
else 
{ 
Debug.WriteLine("< {0}.{1} - after {2} ms", 
input.MethodBase.DeclaringType, input.MethodBase.Name, 
stopwatch.ElapsedMilliseconds); 
} 
Before each method call of decorated class 
After each method call 
public class DependencyConfig 
{ 
public static void Configure(IUnityContainer container) 
{ 
container.AddNewExtension<Interception>(); 
var connectionString = ConfigurationManager.ConnectionStrings["BankingDbContext"] 
.ConnectionString; 
container.RegisterType<IAccountRepository, AccountRepository>( 
new InjectionConstructor(connectionString), 
new Interceptor<InterfaceInterceptor>(), 
new InterceptionBehavior<TimingBehavior>()); 
container.RegisterType<IUserAccountService, UserAccountService>( 
new Interceptor<InterfaceInterceptor>(), 
new InterceptionBehavior<TimingBehavior>()); 
} 
}
TO CONCLUDE …
Things to remember 
• DI Patterns … 
– Don’t be a Control Freak 
– Constructor Injection is your friend 
– Compose you object graphs in one place 
– DI Containers are powerful but not magical 
• … can help you achieve loosely coupled code 
– Maintainable 
– Testable
Going further … 
• Mark Seemann’s book 
and blog posts 
– http://blog.ploeh.dk/ 
• Conversation about DI 
in aspnet vNext 
– http://forums.asp.net/t/1989008.aspx?Feedback+ 
on+ASP+NET+vNext+Dependency+Injection 
• SOLID principles
Shoot ! 
Q&A
Contact : @tsimbalar 
THANKS FOR ATTENDING !
You want more ? 
EXTRAS
Late-binding 
• Dynamically decide which implementation to 
protectuedsoeverride IController GetControllerInstance(RequestContext requestContext, 
Type controllerType) 
{ 
// how to compose an AccountController ? 
if (controllerType == typeof(AccountController)) 
{ 
var repo = LoadInstanceFromPluginFolder<IAccountRepository>(); 
Plugin scenarios – scan assemblies in a folder for implementations 
var service = new UserAccountService(repo); 
return new AccountController(service); 
} 
// standard way in MVC to use default strategy 
return base.GetControllerInstance(requestContext, controllerType);
LifeTime Management
anti-pattern : Service Locator
SOLID 
Single Responsibility Principle 
Open Closed Principle 
Liskov Substitution Principle 
Interface Segregation Principle 
Dependency Inversion Principe
Ad

More Related Content

What's hot (20)

ASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with OverviewASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with Overview
Shahed Chowdhuri
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
guest11106b
 
Model View Controller (MVC)
Model View Controller (MVC)Model View Controller (MVC)
Model View Controller (MVC)
Javier Antonio Humarán Peñuñuri
 
MVC Architecture
MVC ArchitectureMVC Architecture
MVC Architecture
Prem Sanil
 
Design Pattern - Factory Method Pattern
Design Pattern - Factory Method PatternDesign Pattern - Factory Method Pattern
Design Pattern - Factory Method Pattern
Mudasir Qazi
 
ASP.NET - Life cycle of asp
ASP.NET - Life cycle of aspASP.NET - Life cycle of asp
ASP.NET - Life cycle of asp
priya Nithya
 
Dependency injection ppt
Dependency injection pptDependency injection ppt
Dependency injection ppt
Swati Srivastava
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
Venkata Naga Ravi
 
Spring Web MVC
Spring Web MVCSpring Web MVC
Spring Web MVC
zeeshanhanif
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
Jeevesh Pandey
 
Spring annotation
Spring annotationSpring annotation
Spring annotation
Rajiv Srivastava
 
Servlets
ServletsServlets
Servlets
ZainabNoorGul
 
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Arjun Thakur
 
Unit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptxUnit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptx
Malla Reddy University
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and Netty
Constantine Slisenka
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
habib_786
 
Iterator Design Pattern
Iterator Design PatternIterator Design Pattern
Iterator Design Pattern
Varun Arora
 
Observer design pattern
Observer design patternObserver design pattern
Observer design pattern
Sara Torkey
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
Eberhard Wolff
 
Dependency injection and inversion
Dependency injection and inversionDependency injection and inversion
Dependency injection and inversion
chhabraravish23
 
ASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with OverviewASP.NET Core MVC + Web API with Overview
ASP.NET Core MVC + Web API with Overview
Shahed Chowdhuri
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
guest11106b
 
MVC Architecture
MVC ArchitectureMVC Architecture
MVC Architecture
Prem Sanil
 
Design Pattern - Factory Method Pattern
Design Pattern - Factory Method PatternDesign Pattern - Factory Method Pattern
Design Pattern - Factory Method Pattern
Mudasir Qazi
 
ASP.NET - Life cycle of asp
ASP.NET - Life cycle of aspASP.NET - Life cycle of asp
ASP.NET - Life cycle of asp
priya Nithya
 
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Arjun Thakur
 
Unit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptxUnit 1 - TypeScript & Introduction to Angular CLI.pptx
Unit 1 - TypeScript & Introduction to Angular CLI.pptx
Malla Reddy University
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and Netty
Constantine Slisenka
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
habib_786
 
Iterator Design Pattern
Iterator Design PatternIterator Design Pattern
Iterator Design Pattern
Varun Arora
 
Observer design pattern
Observer design patternObserver design pattern
Observer design pattern
Sara Torkey
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
Eberhard Wolff
 
Dependency injection and inversion
Dependency injection and inversionDependency injection and inversion
Dependency injection and inversion
chhabraravish23
 

Viewers also liked (20)

Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Fabien Potencier
 
Inversion of Control - Introduction and Best Practice
Inversion of Control - Introduction and Best PracticeInversion of Control - Introduction and Best Practice
Inversion of Control - Introduction and Best Practice
Lars-Erik Kindblad
 
Functional Dependency Injection in C#
Functional Dependency Injection in C#Functional Dependency Injection in C#
Functional Dependency Injection in C#
Thomas Jaskula
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency Injection
Theo Jungeblut
 
IoC and Mapper in C#
IoC and Mapper in C#IoC and Mapper in C#
IoC and Mapper in C#
Huy Hoàng Phạm
 
Dependency Injection in .NET
Dependency Injection in .NETDependency Injection in .NET
Dependency Injection in .NET
Remik Koczapski
 
Dependency injection for beginners
Dependency injection for beginnersDependency injection for beginners
Dependency injection for beginners
Bhushan Mulmule
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Introduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionIntroduction to Spring's Dependency Injection
Introduction to Spring's Dependency Injection
Richard Paul
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
HAO-WEN ZHANG
 
Dependency Injection And Ioc Containers
Dependency Injection And Ioc ContainersDependency Injection And Ioc Containers
Dependency Injection And Ioc Containers
Tim Murphy
 
Functional programming in C#
Functional programming in C#Functional programming in C#
Functional programming in C#
Thomas Jaskula
 
Dependency injection with Symfony 2
Dependency injection with Symfony 2Dependency injection with Symfony 2
Dependency injection with Symfony 2
cammanderson
 
MVVM - Model View ViewModel
MVVM - Model View ViewModelMVVM - Model View ViewModel
MVVM - Model View ViewModel
Dareen Alhiyari
 
Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax Basics
Richard Paul
 
Hash map
Hash mapHash map
Hash map
Emmanuel Fuchs
 
Spring IOC and DAO
Spring IOC and DAOSpring IOC and DAO
Spring IOC and DAO
AnushaNaidu
 
EJB and CDI - Alignment and Strategy
EJB and CDI - Alignment and StrategyEJB and CDI - Alignment and Strategy
EJB and CDI - Alignment and Strategy
David Delabassee
 
System Integration with Akka and Apache Camel
System Integration with Akka and Apache CamelSystem Integration with Akka and Apache Camel
System Integration with Akka and Apache Camel
krasserm
 
Inversion of Control - Introduction and Best Practice
Inversion of Control - Introduction and Best PracticeInversion of Control - Introduction and Best Practice
Inversion of Control - Introduction and Best Practice
Lars-Erik Kindblad
 
Functional Dependency Injection in C#
Functional Dependency Injection in C#Functional Dependency Injection in C#
Functional Dependency Injection in C#
Thomas Jaskula
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency Injection
Theo Jungeblut
 
Dependency Injection in .NET
Dependency Injection in .NETDependency Injection in .NET
Dependency Injection in .NET
Remik Koczapski
 
Dependency injection for beginners
Dependency injection for beginnersDependency injection for beginners
Dependency injection for beginners
Bhushan Mulmule
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Introduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionIntroduction to Spring's Dependency Injection
Introduction to Spring's Dependency Injection
Richard Paul
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
HAO-WEN ZHANG
 
Dependency Injection And Ioc Containers
Dependency Injection And Ioc ContainersDependency Injection And Ioc Containers
Dependency Injection And Ioc Containers
Tim Murphy
 
Functional programming in C#
Functional programming in C#Functional programming in C#
Functional programming in C#
Thomas Jaskula
 
Dependency injection with Symfony 2
Dependency injection with Symfony 2Dependency injection with Symfony 2
Dependency injection with Symfony 2
cammanderson
 
MVVM - Model View ViewModel
MVVM - Model View ViewModelMVVM - Model View ViewModel
MVVM - Model View ViewModel
Dareen Alhiyari
 
Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax Basics
Richard Paul
 
Spring IOC and DAO
Spring IOC and DAOSpring IOC and DAO
Spring IOC and DAO
AnushaNaidu
 
EJB and CDI - Alignment and Strategy
EJB and CDI - Alignment and StrategyEJB and CDI - Alignment and Strategy
EJB and CDI - Alignment and Strategy
David Delabassee
 
System Integration with Akka and Apache Camel
System Integration with Akka and Apache CamelSystem Integration with Akka and Apache Camel
System Integration with Akka and Apache Camel
krasserm
 
Ad

Similar to Dependency injection - the right way (20)

Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
sriram sarwan
 
Jasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casJasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-cas
ellentuck
 
Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)
guiwoda
 
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Dan Wahlin
 
Cbse computer science (c++) class 12 board project bank managment system
Cbse computer science (c++)  class 12 board project  bank managment systemCbse computer science (c++)  class 12 board project  bank managment system
Cbse computer science (c++) class 12 board project bank managment system
pranoy_seenu
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong Foundations
Salesforce Developers
 
Yii Introduction
Yii IntroductionYii Introduction
Yii Introduction
Jason Ragsdale
 
A Unified View of Modeling and Programming
A Unified View of Modeling and ProgrammingA Unified View of Modeling and Programming
A Unified View of Modeling and Programming
Ed Seidewitz
 
Jsf intro
Jsf introJsf intro
Jsf intro
vantinhkhuc
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
Jenya Terpil
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
FDConf
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
goodfriday
 
ELEVATE Paris
ELEVATE ParisELEVATE Paris
ELEVATE Paris
Peter Chittum
 
Paul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & syncPaul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & sync
mdevtalk
 
1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org
AbbyWhyte974
 
1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org
MartineMccracken314
 
From CRUD to messages: a true story
From CRUD to messages: a true storyFrom CRUD to messages: a true story
From CRUD to messages: a true story
Alessandro Melchiori
 
Refatorando com a API funcional do Java
Refatorando com a API funcional do JavaRefatorando com a API funcional do Java
Refatorando com a API funcional do Java
Giovane Liberato
 
Asp.NET MVC
Asp.NET MVCAsp.NET MVC
Asp.NET MVC
vrluckyin
 
SQL Server 2008 Portfolio
SQL Server 2008 PortfolioSQL Server 2008 Portfolio
SQL Server 2008 Portfolio
anthonyfeliciano
 
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
sriram sarwan
 
Jasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casJasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-cas
ellentuck
 
Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)
guiwoda
 
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Dan Wahlin
 
Cbse computer science (c++) class 12 board project bank managment system
Cbse computer science (c++)  class 12 board project  bank managment systemCbse computer science (c++)  class 12 board project  bank managment system
Cbse computer science (c++) class 12 board project bank managment system
pranoy_seenu
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong Foundations
Salesforce Developers
 
A Unified View of Modeling and Programming
A Unified View of Modeling and ProgrammingA Unified View of Modeling and Programming
A Unified View of Modeling and Programming
Ed Seidewitz
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
Jenya Terpil
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
FDConf
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
goodfriday
 
Paul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & syncPaul Lammertsma: Account manager & sync
Paul Lammertsma: Account manager & sync
mdevtalk
 
1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org
AbbyWhyte974
 
1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org1-What are the opportunities and threats that could impact the org
1-What are the opportunities and threats that could impact the org
MartineMccracken314
 
From CRUD to messages: a true story
From CRUD to messages: a true storyFrom CRUD to messages: a true story
From CRUD to messages: a true story
Alessandro Melchiori
 
Refatorando com a API funcional do Java
Refatorando com a API funcional do JavaRefatorando com a API funcional do Java
Refatorando com a API funcional do Java
Giovane Liberato
 
Ad

Recently uploaded (20)

Societal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainabilitySocietal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainability
Jordi Cabot
 
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
Andre Hora
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
Exploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the FutureExploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the Future
ICS
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage DashboardsAdobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
BradBedford3
 
Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
How can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptxHow can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptx
laravinson24
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 
Societal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainabilitySocietal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainability
Jordi Cabot
 
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
Andre Hora
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
Exploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the FutureExploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the Future
ICS
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage DashboardsAdobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
BradBedford3
 
Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
How can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptxHow can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptx
laravinson24
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 

Dependency injection - the right way

  • 2. Dependency Injection, the right way Thibaud DESODT @tsimbalar
  • 3. This talk • What it is about – Dependency Injection (DI) patterns – Benefits – Common pitfalls • What it is not about – Specific IoC/DI Container implementations • Pre-requisites – OOP – Class-based statically-typed languages • Based on examples
  • 5. What ? DEPENDENCY INJECTION
  • 6. Dependency Injection Dependency Injection is a set of practices that allow to build loosely coupled applications
  • 7. Dependency Injection Dependency Injection is a set of practices that allow to build loosely coupled applications It’s NOT : – A library – A framework – A tool It IS : - A way of thinking - A way of designing code - General guidelines
  • 8. Dependency Injection Dependency Injection is a set of practices that allow to build loosely coupled applications Small components … - Independent - Reusable - Interchangeable … plugged together to form a bigger system Benefits : - Small classes with single responsibility - Easier maintenance - Extensibility - Testable
  • 9. Show me the code ! FROM TIGHTLY TO LOOSELY COUPLED
  • 10. Example : Boring Bank™ System • Features – User can list his accounts – User can rename his accounts – User can transfer money from an account to the other • Tech : – Web front-end – Relational database
  • 11. Starting from scratch public class AccountController : BaseController { // GET: Account [HttpGet] public ActionResult Index() { var userId = this.User.AsClaimsPrincipal().UserId(); using (var context = new BankingDbContext()) { var accounts = context.Accounts .Where(a => a.CustomerId == userId) .OrderBy(a => a.Title).ToList(); return View(accounts); } } [HttpPost] public ActionResult TransferPost(int from, int to, decimal amount) { var userId = this.User.AsClaimsPrincipal().UserId(); using (var context = new BankingDbContext()) { var accountFrom = context.Accounts .Single(a => a.CustomerId == userId && a.Id == from); var accountTo = context.Accounts .Single(a => a.CustomerId == userId && a.Id == to); accountFrom.Balance -= amount; accountTo.Balance += amount; context.SaveChanges(); return RedirectToAction("Index"); } } data business presentation
  • 12. Tightly-coupled code • Using another kind of UI ? • Using another kind of storage ? • Using the business rules somewhere else ?
  • 13. Separation of Concerns • Layered architecture / split assemblies – Presentation – Business – Data-access (Repository) • Separated : – Persistence Entities – Domain Entities – View Models
  • 14. public class AccountController : BaseController public Account GetAccountForCustomer(int customerId, int accountId) { // GET: Account [HttpGet] public ActionResult Index() { var userId = this.User.AsClaimsPrincipal().UserId(); public void Transfer(int userId, int fromAccountId, int toAccountId, decimal amountToTransfer var userAccountService = new UserAccountService(); var accounts = userAccountService.GetAccountsForCustomer(userId); return View(ToViewModel(accounts)); } [HttpPost] public ActionResult TransferPost(int from, int to, decimal amount) { var userId = this.User.AsClaimsPrincipal().UserId(); var userAccountService = new UserAccountService(); userAccountService.Transfer(userId, from, to, amount); return RedirectToAction("Index"); } AccountController.cs (WebPortal) UI talks to Business { // TODO : validate arguments var accountRepository = new AccountRepository(); var fromAccount = accountRepository.GetAccountForCustomer(userId, fromAccountId); var toAccount = accountRepository.GetAccountForCustomer(userId, toAccountId); // TODO : verify that there is enough money fromAccount.Balance -= amountToTransfer; toAccount.Balance += amountToTransfer; accountRepository.Update(fromAccount); accountRepository.Update(toAccount); } UserAccountService.cs (Business) Business talks to Data { using (var context = new BankingDbContext("BankingDbContext")) { var account = context.Accounts .Single(a => a.CustomerId == customerId && a.Id == accountId); return account; } } public void Update(Account account) { using (var context = new BankingDbContext("BankingDbContext")) { var accountEf = context.Accounts.Find(account.Id); // theoretically, could do "if not changed" accountEf.Balance = account.Balance; accountEf.Title = account.Title; context.SaveChanges(); } } AccountRepository.cs (Data)
  • 15. That looks fine … but is it ?
  • 16. anti-pattern : Control Freak • Symptoms: – Code insists on how the dependencies are built – Makes it impossible to use component in isolation – Not testable without full stack • Easy to spot : new everywhere AccountController : BaseController Account HttpGet] ActionResult Index() userId = this.User.AsClaimsPrincipal().UserId(); userAccountService = new UserAccountService(); accounts = userAccountService.GetAccountsForCustomer(userId); return View(ToViewModel(accounts)); public void Transfer(int userId, int fromAccountId, int toAccountId { // TODO : validate arguments var accountRepository = new AccountRepository(); var fromAccount = accountRepository.GetAccountForCustomer var toAccount = accountRepository.GetAccountForCustomer // TODO : verify that there is enough money fromAccount.Balance -= amountToTransfer; toAccount.Balance += amountToTransfer; accountRepository.Update(fromAccount); accountRepository.Update(toAccount); }
  • 17. Unit tests as a Coupling Detector • Unit tests are “just another client” for your code • If unit tests are hard to write, the code is probably too tightly coupled -> Let’s make it testable !
  • 18. Making it testable - Properties public class UserAccountService { [TestMethod] public void RenameAccount_must_UpdateAccountName() { public UserAccountService() { AccountRepository = new AccountRepository("BankingContext"); } #region Dependency Management public AccountRepository AccountRepository { get; set; } #endregion Settable property allows to “inject” another instance // Arrange var newName = "someName"; var existingAccount = AnAccount(); var sut = new UserAccountService(); sut.AccountRepository = FAIL FAIL//I want to put a fake here ! // Act sut.RenameAccount(existingAccount.CustomerId, existingAccount.Id, newName); // Assert // I want to verify what happened .. } In UserAccountServiceTest.cs , in test project Business.Tests
  • 19. Programming to an interface public class UserAccountService : IUserAccountService [TestMethod] { public void RenameAccount_must_UpdateAccountName() { public UserAccountService() { // Arrange var newName = "someName"; AccountRepository = new AccountRepository("BankingContext"); } var existingAccount = AnAccount(); #region Dependency Management var mockRepo = new Mock<IAccountRepository>(); mockRepo.Setup(r => r.GetAccountForCustomer(It.IsAny<int>(), It.IsAny<int>())) public IAccountRepository AccountRepository { get; set; } .Returns(existingAccount); var sut = new UserAccountService(); sut.AccountRepository = mockRepo.Object; //I want to put a fake here ! #endregion Use an interface (or abstract class) instead of concrete class // Act sut.RenameAccount(existingAccount.CustomerId, existingAccount.Id, newName); // Assert mockRepo.Verify(r=> r.Update(It.Is<Data.Account>(a=> a.Title == newName))); } Inject fake instance
  • 20. pattern : Property Injection Expose settable properties to modify dependencies Benefits • Useful to provide optional extensibility • There must be a good “local default” implementation Caveats • Not very easy to discover point of extension • Easy to forget • Extra care to avoid NullReferenceExceptions, handle thread-safety etc
  • 21. Making it more explicit - Constructor public class UserAccountService : IUserAccountService { private readonly IAccountRepository _accountRepository; Injection constructor used in tests - declare required dependencies as constructor parameters public UserAccountService(IAccountRepository accountRepository) { public IAccountRepository AccountRepository { get { return _accountRepository; if (accountRepository == null) throw new ArgumentNullException("accountRepository _accountRepository = accountRepository; } public UserAccountService() :this(new AccountRepository("BankingContext")) { } #region Dependency Management Default constructor used in production code [TestMethod] public void RenameAccount_must_UpdateAccountName() { // Arrange var newName = "someName"; var existingAccount = AnAccount(); var mockRepo = new Mock<IAccountRepository>(); mockRepo.Setup(r => r.GetAccountForCustomer(It.IsAny<int>(), It.IsAny<int>())) .Returns(existingAccount); var sut = new UserAccountService(mockRepo.Object); // Act sut.RenameAccount(existingAccount.CustomerId, existingAccount.Id, newName); // Assert mockRepo.Verify(r=> r.Update(It.Is<Data.Account>(a=> a.Title == newName))); } Inject fake instance
  • 22. anti-pattern : Bastard Injection Enable dependencies for testing, but use hard-code implementation in production code • Paradox: – Lots of efforts to reduce coupling – … but forcing a hard-coded value • Test-specific code • Ambiguity
  • 23. Cutting the dependency chain public class AccountController : BaseController { private readonly IUserAccountService _userAccountService; public class UserAccountService : IUserAccountService Only 1 constructor - dependencies passed as constructor arguments { public private AccountController(readonly IAccountRepository IUserAccountService _accountRepository; userAccountService) { if (userAccountService == null) throw new ArgumentNullException("userAccountService _userAccountService = userAccountService; } public UserAccountService(IAccountRepository accountRepository) { if (accountRepository == null) throw new ArgumentNullException("accountRepository _accountRepository = accountRepository; AccountController (WebPortal) } UserAccountService.cs (Business)
  • 24. pattern : Constructor Injection Declare required dependencies as constructor parameters • Declarative • Discoverable (Intellisense, Reflection …) • Recommended approach in 99.9% of cases • Easy to implement Need Guard clause because C# does not support non-nullable reference types …
  • 26. This is great and everything except … [InvalidOperationException: An error occurred when trying to create a controller of 'BoringBank.WebPortal.Controllers.AccountController'. Make sure that the controller System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext
  • 27. The chicken and the egg IAccountRepository repo = new IAccountRepository(); • Ideal world: Programming to interfaces vs • Real world : applications do not work with only interfaces • Class instances have to be created and assembled (=composed) at some point • This happens only in one place in an application
  • 28. pattern : Composition Root Composition of classes into a larger system should happen only in one place • Create one object-graph • As late as possible • Only part of the code that can reference concrete types Where ? • Only applications have a Composition Root • There is no Composition Root in a class library • Extension point depends on the kind of app
  • 29. ASP.NET MVC Composition Root public class AppCompositionRoot : DefaultControllerFactory • IControllerFactory • Creates a controller instance based on URL • DefaultControllerFactory uses default constructor on Controller • … but it can be changed ! { protected override IController GetControllerInstance(RequestContext requestContext Type controllerType) { // how to compose an AccountController ? if (controllerType == typeof(AccountController)) { var connectionString = ConfigurationManager .ConnectionStrings["BankingDbContext"].ConnectionString; var repo = new AccountRepository(connectionString); var service = new UserAccountService(repo); return new AccountController(service); Controller composition } // standard way in MVC to use default strategy return base.GetControllerInstance(requestContext, controllerType); } } public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { var factory = new AppCompositionRoot(); ControllerBuilder.Current.SetControllerFactory(factory); In Global.asax tell MVC to use our composition root
  • 30. Pure DI (aka Poor Man’s DI) Manual wiring of dependencies • Very explicit (no « magic ») • Type-safe • … but repetitive and boring var connectionString = ConfigurationManager .ConnectionStrings["BankingDbContext"].ConnectionString; var repo = new AccountRepository(connectionString); var service = new UserAccountService(repo); return new AccountController(service);
  • 31. And we did that because … ? SO WHAT ?
  • 32. Benefits of full DI-friendly codebase • Testability • Maintainability • Allows parallel work • … and more ! • Defined in a centralized location
  • 33. Reusability / Extensibility or CLI or WPF or Web API or WCF … or files or NoSQL or Azure or Http Client …
  • 34. Extensibility public class CachedAccountRepository : IAccountRepository { private readonly ICache _cache; private readonly IAccountRepository _decorated; • Decorator Pattern public CachedAccountRepository(ICache cache, IAccountRepository decorated) { – Very DI-friendly pattern var nakedRepo = new AccountRepository(connectionString); if (cache == null) throw new ArgumentNullException("cache"); if (decorated == null) throw new ArgumentNullException("decorated"); _cache = cache; _decorated = decorated; // decorate the nakedRepository with caching features var • Example longCache = : new caching DotNetCache(TimeSpan.FromHours(1)); var cachedRepo = new CachedAccountRepository(longCache, nakedRepo); var service } = new UserAccountService(cachedRepo); public IReadOnlyList<Account> GetAccountsForCustomer(int userId) { var accounts = _cache.GetOrAdd("accounts_" + userId, () => _decorated.GetAccountsForCustomer(userId)); return accounts; } Decorator delegate to decorated instance
  • 36. DI Container – how they work • Mapping Abstraction-> Concrete Type – Usually initialized on app start – Methods like Register<IAbstraction,ConcreteType>() • Method Resolve<TRequired>() • Recursively resolves dependencies reading constructor parameters
  • 37. public class DependencyConfig Example - Unity { public static void Configure(IUnityContainer container) { var connectionString = ConfigurationManager.ConnectionStrings["BankingDbContext" public class MvcApplication : System.Web.HttpApplication { public class AppCompositionRoot : DefaultControllerFactory protected void Application_Start() { private readonly IUnityContainer _unityContainer; var container = new UnityContainer(); DependencyConfig.Configure(container); var compositionRoot = new AppCompositionRoot(container); ControllerBuilder.Current.SetControllerFactory(compositionRoot { In Global.asax .ConnectionString; container.RegisterType<IAccountRepository, AccountRepository>( new InjectionConstructor(connectionString)); container.RegisterType<IUserAccountService, UserAccountService>(); } } public AppCompositionRoot(IUnityContainer unityContainer) { In DependencyConfig if (unityContainer == null) throw new ArgumentNullException("unityContainer _unityContainer = unityContainer; } protected override IController GetControllerInstance(RequestContext requestContext controllerType) { return (IController) _unityContainer.Resolve(controllerType); } } In CompositionRoot Register / Resolve (/ Release)
  • 38. Aspects of DI • Composition • Lifetime Management • Interception
  • 39. Interception • ~ Dynamic Decorators • Cross-cutting concerns – Logging – Auditing – Profiling … • AOP-like !
  • 40. public class TimingBehavior : IInterceptionBehavior { public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext { var stopwatch = new Stopwatch(); // Before invoking the method on the original target. Debug.WriteLine("> {0}.{1}", input.MethodBase.DeclaringType, input.MethodBase.Name); stopwatch.Start(); // Invoke the next behavior in the chain. var result = getNext()(input, getNext); stopwatch.Stop(); // After invoking the method on the original target. if (result.Exception != null) { Debug.WriteLine( Call to decorated instance "< {0}.{1} failed - after {3} ms", input.MethodBase.DeclaringType, input.MethodBase.Name, result.Exception.GetType(), stopwatch.ElapsedMilliseconds); } else { Debug.WriteLine("< {0}.{1} - after {2} ms", input.MethodBase.DeclaringType, input.MethodBase.Name, stopwatch.ElapsedMilliseconds); } Before each method call of decorated class After each method call public class DependencyConfig { public static void Configure(IUnityContainer container) { container.AddNewExtension<Interception>(); var connectionString = ConfigurationManager.ConnectionStrings["BankingDbContext"] .ConnectionString; container.RegisterType<IAccountRepository, AccountRepository>( new InjectionConstructor(connectionString), new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<TimingBehavior>()); container.RegisterType<IUserAccountService, UserAccountService>( new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<TimingBehavior>()); } }
  • 42. Things to remember • DI Patterns … – Don’t be a Control Freak – Constructor Injection is your friend – Compose you object graphs in one place – DI Containers are powerful but not magical • … can help you achieve loosely coupled code – Maintainable – Testable
  • 43. Going further … • Mark Seemann’s book and blog posts – http://blog.ploeh.dk/ • Conversation about DI in aspnet vNext – http://forums.asp.net/t/1989008.aspx?Feedback+ on+ASP+NET+vNext+Dependency+Injection • SOLID principles
  • 45. Contact : @tsimbalar THANKS FOR ATTENDING !
  • 46. You want more ? EXTRAS
  • 47. Late-binding • Dynamically decide which implementation to protectuedsoeverride IController GetControllerInstance(RequestContext requestContext, Type controllerType) { // how to compose an AccountController ? if (controllerType == typeof(AccountController)) { var repo = LoadInstanceFromPluginFolder<IAccountRepository>(); Plugin scenarios – scan assemblies in a folder for implementations var service = new UserAccountService(repo); return new AccountController(service); } // standard way in MVC to use default strategy return base.GetControllerInstance(requestContext, controllerType);
  • 50. SOLID Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principe

Editor's Notes

  • #3: Present you self
  • #4: Talk about Dependency Injection Dependency Injection patterns You may know about it under a form or another, or ay have used tools Who has ? You must unlearn ! Need to understand the philosophy and concepts in order to use the tools properly It’s easy to misuse the tools and miss some benefits
  • #5: There is no magic !
  • #12: Let’s see … Inside a controller Creating a dbcontext (Entity Framework) … imagine if that was ADO .NET Selecting a few things Passing it to the view… Has anybody ever written code like that ? That’s only a read page … imagine action with side effects… Simplified, no error handling whatsoever You may argue that it is loosely coupled … there’s only one class … but what a class !
  • #14: Turned spaghetti into lasagna 
  • #16: Business depends on Data layer … it should be an implementation detail Presentation depends on Business which depends on Data … which depends on EF … we’ll see that a bit later But mostly about using components in isolation … this is not testable right now
  • #18: Comment : First encounter with need for loosely coupled code came from unit tests Who write unit tests here ? Anybody who writes unit tests first ? First encounter where you code MUST BE loosely coupled : unit tests ! Actually consume components out of the scope of the application Tightly coupled code is hard to test or not testable at all … if it’s testable it’s not too tightly coupled
  • #20: Interface of abstract class …. I can’t do new I….. The closest we can get is this …. Note that even though we introduced interfaces, we still have a hard reference between all projects
  • #23: Used in default Visual Studio Template for MVC apps until not so long ago
  • #24: Comment about moving the interface into business Where to put the interface ? Separate project “Abstractions” ? The consumer owns the interface
  • #25: If you remember one thing, it’s that !
  • #30: Top down
  • #34: Can be done with Adapter pattern
  • #35: Traditionnal approach would be : Modify code Subclass..