SlideShare una empresa de Scribd logo
1 de 66
ependency Injection vs. Inversion of Contr
(meDIOCre presentation)
Oleksandr Valetskyy
Technical Leader
SoftServe
ependency Injection vs. Inversion of Contr
(meDIOCre presentation)
Oleksandr Valetskyy
Technical Leader
SoftServe
ependency Injection vs. Inversion of Contr
Just Do It!
Oleksandr Valetskyy
Technical Leader
SoftServe
ependency Injection vs. Inversion of Contr
Just Do It!
Oleksandr Valetskyy
Technical Leader
SoftServe
About me
Agenda
Dependency Injection
(DI)
Definition
Benefits and purpose
Common
misconceptions
DI patterns &
antipatterns
Inversion of Control
(IoC)
Definition
Purpose
IoC containers
Summary
Agenda
Dependency Injection (DI) definition
It is a design principle in which code
creating a new object supplies the
other objects that are required for it to
function.
Dependency Injection is a set of software
design principles and patterns that enable us to
develop loosely coupled code.
Detour - loose coupling
Loose coupling gives
flexibility and ability to swap
concrete implementations
Components should be
independent and have as little
knowledge of other
components of the system as
possible
Dependency Injection Benefits
More structured and readable
code
Eliminates unnecessary
dependencies
Simplifies testing
Gives opportunity for better
reuse
Enables parallel development
of features in complex
systems
Dependency Injection Purpose
Deliver working software in
the most efficient way
Provide maintainability and
ability to change
Give chance for extension in
the future
Dependency Injection Purpose
Deliver working software in
the most efficient way
Provide maintainability and
ability to change
Give chance for extension in
the future
DI example
public RavenFileSystem(InMemoryRavenConfiguration config, string name, TransportState receivedTransportState = null)
{
ExtensionsState = new AtomicDictionary<object>();
Name = name;
ResourceName = string.Concat(Constants.FileSystem.UrlPrefix, "/", name);
configuration = config;
try
{
ValidateStorage();
configuration.Container.SatisfyImportsOnce(this);
transportState = receivedTransportState ?? new TransportState();
storage = CreateTransactionalStorage(configuration);
sigGenerator = new SigGenerator();
fileLockManager = new FileLockManager();
BufferPool = new BufferPool(1024 * 1024 * 1024, 65 * 1024);
conflictDetector = new ConflictDetector();
conflictResolver = new ConflictResolver(storage, new CompositionContainer(configuration.Catalog));
notificationPublisher = new NotificationPublisher(transportState);
synchronizationTask = new SynchronizationTask(storage, sigGenerator, notificationPublisher, configuration);
metricsCounters = new MetricsCountersManager();
search = new IndexStorage(name, configuration);
conflictArtifactManager = new ConflictArtifactManager(storage, search);
TimerManager = new ResourceTimerManager();
Tasks = new TaskActions(this, Log);
Files = new FileActions(this, Log);
Synchronizations = new SynchronizationActions(this, Log);
// ...
}
}
ravendb/Raven.Database/FileSystem/RavenFileSystem.cs
Common misconceptions about DI
DI is only relevant for late
binding.
DI is only relevant for unit
testing.
DI is a sort of Abstract
Factory on steroids.
DI requires a DI container.
TL;DR
DI is nothing more than a collection of design
principles and patterns.
It’s more about a way of thinking and designing
code than it is about tools and techniques.
Important note: loose coupling and DI should be
pervasive in order to be effective. It should be
everywhere in your code base*.
DI patterns #1: Constructor Injection
Naturally enforces all required dependencies for a
class; Guard Clauses/Code Contracts prohibit misuse
Usual “go to” recommended approach to use during
everyday work
Hint: think about class constructor as static
dependencies declaration
public StreamReader(Stream stream)
: this(stream, true) {
}
public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
: this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize, false) {
}
public StreamReader(Stream stream, Encoding encoding)
: this(stream, encoding, true, DefaultBufferSize, false) {
}
public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks)
: this(stream, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize, false) {
}
public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
: this(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, false) {
}
public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
{
// ..
}
public StreamReader(String path)
: this(path, true) {
}
public StreamReader(String path, bool detectEncodingFromByteOrderMarks)
: this(path, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}
public StreamReader(String path, Encoding encoding)
: this(path, encoding, true, DefaultBufferSize) {
}
public StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks)
: this(path, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}
public StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
{
// ..
}
coreclr/src/mscorlib/src/System/IO/StreamReader.csCI example
Refactoring tightly coupled class to leverage CI
public class Consumer
{
#region Public methods
public void Process()
{
if (AuthenticationService.Instance.Authenticated())
{
var result = ConfigurationService.Instance.GetConfig();
LoggingService.Instance.Log(result);
// ...
}
}
#endregion
}
Refactored class with CI
public class Consumer
{
private readonly IAuthenticationService _authenticationService;
private readonly IConfigurationService _configurationService;
private readonly ILoggingService _loggingService;
public Consumer(IAuthenticationService authenticationService,
IConfigurationService configurationService, ILoggingService loggingService)
{
if (authenticationService == null)
throw new ArgumentNullException(nameof(authenticationService));
if (configurationService == null)
throw new ArgumentNullException(nameof(configurationService));
if (loggingService == null)
throw new ArgumentNullException(nameof(loggingService));
_authenticationService = authenticationService;
_configurationService = configurationService;
_loggingService = loggingService;
}
public void Process()
{
if (_authenticationService.Authenticate())
{
var result = _configurationService.GetConfig();
_loggingService.Log(result);
}
}
}
DI patterns #2: Property (aka Setter)
Injection
Best way to initialize a “good Local
Default” © Mark Seeman
Given the fact it is not mandatory to set
a property as opposed to provide
dependency to a class constructor, think
of PI as a way to describe optional
dependencies
Example: ASP.NET Core globalization & I8n (custom provider
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
{
// Custom request culture logic
return new ProviderCultureResult("en");
}));
});
DI patterns #2: Property (aka Setter)
Injection
public ICache LocalCache { get; set; }
public void Process(IElement element)
{
if (_authenticationService.Authenticate())
{
var config = _configurationService.GetConfig();
_loggingService.Log(config);
if (LocalCache?.Contains(element) == true)
{
//..
}
}
}
// Usage:
var consumer = new Consumer(..);
consumer.LocalCache = new LocalDbCache();
DI patterns #3: Method Injection
Think about this dependency as
some sort of context for operation
(add-in ©)
Try to keep methods “pure” since
state change between calls may
cause unexpected results
/// <summary>
/// Binds a model specified by <paramref name="parameter"/> using <paramref
name="value"/> as the initial value.
/// </summary>
/// <param name="actionContext">The <see cref="ActionContext"/>.</param>
/// <param name="modelBinder">The <see cref="IModelBinder"/>.</param>
/// <param name="valueProvider">The <see cref="IValueProvider"/>.</param>
/// <param name="parameter">The <see cref="ParameterDescriptor"/></param>
/// <param name="metadata">The <see cref="ModelMetadata"/>.</param>
/// <param name="value">The initial model value.</param>
/// <returns>The result of model binding.</returns>
public virtual async Task<ModelBindingResult> BindModelAsync(
ActionContext actionContext,
IModelBinder modelBinder,
IValueProvider valueProvider,
ParameterDescriptor parameter,
ModelMetadata metadata,
object value)
{
// ..
}
MI example Mvc/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Param
eterBinder.cs
DI patterns #4: Ambient context
Static property or method
(accessor) providing a
dependency to every module.
The context must be an
abstraction and the respective
property should be writable so
we could leverage DI
Example: .NET Tracing
public class AmbientContext
{
public void DoTrace()
{
Trace.Listeners.Add(new ConsoleListener());
Trace.WriteLine("Traced message");
}
private class ConsoleListener : TraceListener
{
public override void Write(string message)
{
Console.Write("Custom listener message: " + message);
}
public override void WriteLine(string message)
{
Console.WriteLine("Custom listener message: " + message);
}
}
}
DI patterns #4: Ambient context
public class RealDateTimeProvider : IDateTimeProvider
{
public DateTime Today() { return DateTime.Today; }
}
public static class DateTimeProvider
{
private static IDateTimeProvider _currentDateTimeProvider;
public static IDateTimeProvider Current
{
get { return _currentDateTimeProvider ?? Default; }
set { _currentDateTimeProvider = value; }
}
public static IDateTimeProvider Default = new RealDateTimeProvider();
}
// Context usage:
var today = DateTimeProvider.Current.Today();
// Altering AC if needed:
DateTimeProvider.Current = new MockDateTimeProvider();
DI antipatterns. #1- Control Freak
Class controlling all of its
dependencies by explicitly
instantiating them
Red flag: new keyword all over the
code
Results in inability to control objects
lifetime and being constraint to a
current (tightly coupled)
implementation
Refactoring to interfaces, but still
instantiating objects inside class
does not result in proper DI
DI antipatterns. #2 – Bastard injection
(Test-specific) constructor
defaulting some of the class
dependencies
Increases the amount of implicit
dependencies
Makes choice between constructor
ambiguous, can cause issues with
IoC containers
Result of developers’ attempt to
make code testable without full
understanding of DI*
Example: Ayende Rahien - Reviewing NerdDinner (2009)
DI antipatterns. #3 – Constrained construction
Require a dependency to have a
specific constructor (and throw
exception when mandatory
configuration is not available)
Improper solution for achieving
late binding
DI antipatterns. #4 – Service Locator
Although introduced by Martin
Fowler, is considered an anti-
pattern:
- Hides dependencies
- Causes runtime errors instead
of compile-time
- Amplifies the possibility of
introducing breaking changes
during maintenance
Service Locator is an Anti-Pattern by Mark Seemann
http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/
SOLID Encapsulation
Fighting Dealing with DI anti-patterns
• Decouple logic into separate classes
• Extract interfaces/abstract base classes
• Investigate object runtime behavior, try to
make decision on implementation choosing
as late as possible
• Defer objects creation to Factories
• Don’t forget about created objects lifecycle
(dispose etc.)
• Monitor coupling (NDepend and other tools)
• Think strategy over tactics, don’t over-
refactor (o_O)
Inversion of Control
Inversion of Control (IoC) as a
style of programming in which
the framework takes the control
of the flow instead of your code.
IoC is also known as the
Hollywood Principle: “Don't call
us, we'll call you”
NB: has nothing to do with actual
dependencies passing
Inversion of Control
IoC is an attribute of a
framework. A library may have or
may not have IoC, framework
always will.
DI helps achieve IoC
Martin Fowler - Inversion of Control Containers and the Dependency Injection patte
https://www.martinfowler.com/articles/injection.html
IoC Example – ASP.NET Core Startup.cs
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit
// http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true)
.Build();
var connectionString = config.GetConnectionString("DefaultConnection");
var optionsBuilder = new DbContextOptionsBuilder().UseSqlServer(connectionString);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseStaticFiles();
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMvc();
}
}
Inversion of Control
IoC defers the responsibility of dependencies
creation to a higher level code.
This way we substitute composition with
aggregation and move some of the problems out
of the particular class.
Ideally this responsibility should be propagated to
a single point – so-called Composition Root
Inversion of Control
IoC (the same as DI and other engineering
practices) is not a goal on itself
IoC as design principle that targets complexity
and helps simplify maintenance of big solutions
If it is misused or exaggerated, one should not
expect positive effect
The most usual IoC offender…
… Control Freak/
God Object
DI/IoC Containers
In real world applications, a single class
can have many dependencies, each of
which have their own dependencies
that forms a large graph.
That’s the place where DI container
comes to the rescue.
A DI container should resolve the
dependencies, and this is where the
decision of selecting a concrete class
for the given abstraction should be
made.
NB: “DI” vs. “IoC” containers
Calling container “DI” have
mostly historical roots.
Since IoC is a broader term,
and also because modern
containers support scope
management, lifecycle
management, calls interception
and delayed initialization which
does not fit well into DI
paradigm, it’s more correct to
call them “IoC containers”.
Which container should I choose?
Which container should I choose?
“Building an IoC container in 15 lines of code”
“Building an IoC container in 15 lines of code”
© 2007 Oren Eini aka Ayende Rahien
https://ayende.com/blog/2886/building-an-ioc-container-in-15-lines-of-code
“Building an IoC container in 15 lines of code”
1) Configuration 
2) Lifecycle management
3) Registering service bindings

4) Handling instance activation
Which container should I choose?
Which container should I choose?
• Should it be cross-platform?
Which container should I choose?
• Should it be cross-platform?
• Single vs. multi-threaded resolving
Which container should I choose?
• Should it be cross-platform?
• Single vs. multi-threaded resolving
• Code vs. XML vs. auto-
configuration capabilities
Which container should I choose?
• Should it be cross-platform?
• Single vs. multi-threaded resolving
• Code vs. XML vs. auto-
configuration capabilities
• Do you encounter complex
scenarios that will require custom
objects lifetime management?
Which container should I choose?
• Should it be cross-platform?
• Single vs. multi-threaded resolving
• Code vs. XML vs. auto-
configuration capabilities
• Do you encounter complex
scenarios that will require custom
objects lifetime management?
• Do you need generics/IEnumerable
support?
Which container should I choose?
• Should it be cross-platform?
• Single vs. multi-threaded resolving
• Code vs. XML vs. auto-
configuration capabilities
• Do you encounter complex
scenarios that will require custom
objects lifetime management?
• Do you need generics/IEnumerable
support?
• Will you do complex property/child
containers resolving?
Which container should I choose?
• Should it be cross-platform?
• Single vs. multi-threaded resolving
• Code vs. XML vs. auto-
configuration capabilities
• Do you encounter complex
scenarios that will require custom
objects lifetime management?
• Do you need generics/IEnumerable
support?
• Will you do complex property/child
containers resolving?
• Interception proxy
Which container should I choose?
• Should it be cross-platform?
• Single vs. multi-threaded resolving
• Code vs. XML vs. auto-
configuration capabilities
• Do you encounter complex
scenarios that will require custom
objects lifetime management?
• Do you need generics/IEnumerable
support?
• Will you do complex property/child
containers resolving?
• Interception proxy
IoC containers performance
https://github.com/danielpalme/IocPerformance
https://github.com/stebet/DependencyInjectorBenchmarks
0.00
5000.00
10000.00
15000.00
20000.00
25000.00
Direct LightInject SimpleInjector AspNetCore StructureMap Unity Autofac CastleWindsor Mef Ninject
IoC Containers performance
X86 Legacy JIT
X64 Legacy JIT
X64 RyuJIT
Measure yourself with Benchmark.NET
https://github.com/dotnet/BenchmarkDotNet
Rule of Thumb
The container is used properly when the
application is completely unaware of it’s
existence.
Rule of Thumb
The container is used properly when the
application is completely unaware of it’s
existence.
References:
• Baharestani Daniel - Mastering Ninject for Dependency Injection (Packt Publishing, 2013)
• Seemann Mark - Dependency Injection in .NET (Manning, 2012)
• Martin Fowler - Inversion of Control Containers and the Dependency Injection pattern
(https://www.martinfowler.com/articles/injection.html)
• James Shore - Dependency Injection Demystified (http://www.jamesshore.com/Blog/Dependency-Injection-
Demystified.html)
• Ayende @ Rahien blog (https://ayende.com)
• Sergey Teplyakov blog (http://sergeyteplyakov.blogspot.com)
• Eric Lippert - Immutability in C# Part One: Kinds of Immutability
(https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/)
• Mark Seemann - Service Locator is an Anti-Pattern (http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-
Pattern/)
• Daniel Palme - IoC Container Benchmark - Performance comparison
• (http://www.palmmedia.de/Blog/2011/8/30/ioc-container-benchmark-performance-comparison,
https://github.com/danielpalme/IocPerformance)
• Andrey Akinshin – Benchmark.NET (https://github.com/dotnet/BenchmarkDotNet)
• RavenDB (https://github.com/ravendb/ravendb)
• ASP.NET Core MVC (https://github.com/aspnet/Mvc/)
• Core CLR (https://github.com/dotnet/coreclr)
• Jeremy Clark - Dependency Injection On-Ramp Pluralsight course
(https://app.pluralsight.com/library/courses/dependency-injection-on-ramp/table-of-contents)
• John Sonmez - Practical IoC With ASP.NET MVC 4 Pluralsight course
(https://app.pluralsight.com/library/courses/ioc-aspdotnet-mvc4/table-of-contents)
Thank you!

Más contenido relacionado

La actualidad más candente

JDBC - JPA - Spring Data
JDBC - JPA - Spring DataJDBC - JPA - Spring Data
JDBC - JPA - Spring DataArturs Drozdovs
 
Java căn bản - Chapter12
Java căn bản - Chapter12Java căn bản - Chapter12
Java căn bản - Chapter12Vince Vo
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpaStaples
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Hermann Hueck
 
Hibernate
Hibernate Hibernate
Hibernate Sunil OS
 
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source CodeUsing Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source CodeNicolas Bettenburg
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring DataOliver Gierke
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeletonIram Ramrajkar
 
Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)Pinaki Poddar
 
Entity Persistence with JPA
Entity Persistence with JPAEntity Persistence with JPA
Entity Persistence with JPASubin Sugunan
 
Refactoring Jdbc Programming
Refactoring Jdbc ProgrammingRefactoring Jdbc Programming
Refactoring Jdbc Programmingchanwook Park
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatissimonetripodi
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityWashington Botelho
 

La actualidad más candente (20)

JDBC - JPA - Spring Data
JDBC - JPA - Spring DataJDBC - JPA - Spring Data
JDBC - JPA - Spring Data
 
Java căn bản - Chapter12
Java căn bản - Chapter12Java căn bản - Chapter12
Java căn bản - Chapter12
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpa
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
Hibernate
Hibernate Hibernate
Hibernate
 
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source CodeUsing Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring Data
 
JPA Best Practices
JPA Best PracticesJPA Best Practices
JPA Best Practices
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
 
Java Programming - 08 java threading
Java Programming - 08 java threadingJava Programming - 08 java threading
Java Programming - 08 java threading
 
Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Entity Persistence with JPA
Entity Persistence with JPAEntity Persistence with JPA
Entity Persistence with JPA
 
Refactoring Jdbc Programming
Refactoring Jdbc ProgrammingRefactoring Jdbc Programming
Refactoring Jdbc Programming
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatis
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrity
 
Simple Jdbc With Spring 2.5
Simple Jdbc With Spring 2.5Simple Jdbc With Spring 2.5
Simple Jdbc With Spring 2.5
 

Similar a Oleksandr Valetskyy - DI vs. IoC

Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)David McCarter
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Spring review_for Semester II of Year 4
Spring review_for Semester II of Year 4Spring review_for Semester II of Year 4
Spring review_for Semester II of Year 4than sare
 
Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile appsIvano Malavolta
 
Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Vladimir Kochetkov
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonCodemotion
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedJetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedToru Wonyoung Choi
 
Vpd Virtual Private Database By Saurabh
Vpd   Virtual Private Database By SaurabhVpd   Virtual Private Database By Saurabh
Vpd Virtual Private Database By Saurabhguestd83b546
 
Repository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity FrameworkRepository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenJoshua Long
 
Testing the frontend
Testing the frontendTesting the frontend
Testing the frontendHeiko Hardt
 

Similar a Oleksandr Valetskyy - DI vs. IoC (20)

Tdd,Ioc
Tdd,IocTdd,Ioc
Tdd,Ioc
 
Data access
Data accessData access
Data access
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Struts2 - 101
Struts2 - 101Struts2 - 101
Struts2 - 101
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Test api
Test apiTest api
Test api
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Spring review_for Semester II of Year 4
Spring review_for Semester II of Year 4Spring review_for Semester II of Year 4
Spring review_for Semester II of Year 4
 
Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile apps
 
Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible! Hack an ASP .NET website? Hard, but possible!
Hack an ASP .NET website? Hard, but possible!
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedJetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO Extended
 
CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
 
Vpd Virtual Private Database By Saurabh
Vpd   Virtual Private Database By SaurabhVpd   Virtual Private Database By Saurabh
Vpd Virtual Private Database By Saurabh
 
Repository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity FrameworkRepository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity Framework
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in Heaven
 
Testing the frontend
Testing the frontendTesting the frontend
Testing the frontend
 

Último

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...software pro Development
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 

Último (20)

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

Oleksandr Valetskyy - DI vs. IoC

  • 1. ependency Injection vs. Inversion of Contr (meDIOCre presentation) Oleksandr Valetskyy Technical Leader SoftServe
  • 2. ependency Injection vs. Inversion of Contr (meDIOCre presentation) Oleksandr Valetskyy Technical Leader SoftServe
  • 3. ependency Injection vs. Inversion of Contr Just Do It! Oleksandr Valetskyy Technical Leader SoftServe
  • 4. ependency Injection vs. Inversion of Contr Just Do It! Oleksandr Valetskyy Technical Leader SoftServe
  • 6. Agenda Dependency Injection (DI) Definition Benefits and purpose Common misconceptions DI patterns & antipatterns
  • 8. Dependency Injection (DI) definition It is a design principle in which code creating a new object supplies the other objects that are required for it to function. Dependency Injection is a set of software design principles and patterns that enable us to develop loosely coupled code.
  • 9. Detour - loose coupling Loose coupling gives flexibility and ability to swap concrete implementations Components should be independent and have as little knowledge of other components of the system as possible
  • 10. Dependency Injection Benefits More structured and readable code Eliminates unnecessary dependencies Simplifies testing Gives opportunity for better reuse Enables parallel development of features in complex systems
  • 11. Dependency Injection Purpose Deliver working software in the most efficient way Provide maintainability and ability to change Give chance for extension in the future
  • 12. Dependency Injection Purpose Deliver working software in the most efficient way Provide maintainability and ability to change Give chance for extension in the future
  • 13. DI example public RavenFileSystem(InMemoryRavenConfiguration config, string name, TransportState receivedTransportState = null) { ExtensionsState = new AtomicDictionary<object>(); Name = name; ResourceName = string.Concat(Constants.FileSystem.UrlPrefix, "/", name); configuration = config; try { ValidateStorage(); configuration.Container.SatisfyImportsOnce(this); transportState = receivedTransportState ?? new TransportState(); storage = CreateTransactionalStorage(configuration); sigGenerator = new SigGenerator(); fileLockManager = new FileLockManager(); BufferPool = new BufferPool(1024 * 1024 * 1024, 65 * 1024); conflictDetector = new ConflictDetector(); conflictResolver = new ConflictResolver(storage, new CompositionContainer(configuration.Catalog)); notificationPublisher = new NotificationPublisher(transportState); synchronizationTask = new SynchronizationTask(storage, sigGenerator, notificationPublisher, configuration); metricsCounters = new MetricsCountersManager(); search = new IndexStorage(name, configuration); conflictArtifactManager = new ConflictArtifactManager(storage, search); TimerManager = new ResourceTimerManager(); Tasks = new TaskActions(this, Log); Files = new FileActions(this, Log); Synchronizations = new SynchronizationActions(this, Log); // ... } } ravendb/Raven.Database/FileSystem/RavenFileSystem.cs
  • 14. Common misconceptions about DI DI is only relevant for late binding. DI is only relevant for unit testing. DI is a sort of Abstract Factory on steroids. DI requires a DI container.
  • 15. TL;DR DI is nothing more than a collection of design principles and patterns. It’s more about a way of thinking and designing code than it is about tools and techniques. Important note: loose coupling and DI should be pervasive in order to be effective. It should be everywhere in your code base*.
  • 16. DI patterns #1: Constructor Injection Naturally enforces all required dependencies for a class; Guard Clauses/Code Contracts prohibit misuse Usual “go to” recommended approach to use during everyday work Hint: think about class constructor as static dependencies declaration
  • 17. public StreamReader(Stream stream) : this(stream, true) { } public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks) : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize, false) { } public StreamReader(Stream stream, Encoding encoding) : this(stream, encoding, true, DefaultBufferSize, false) { } public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks) : this(stream, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize, false) { } public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize) : this(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, false) { } public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen) { // .. } public StreamReader(String path) : this(path, true) { } public StreamReader(String path, bool detectEncodingFromByteOrderMarks) : this(path, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) { } public StreamReader(String path, Encoding encoding) : this(path, encoding, true, DefaultBufferSize) { } public StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks) : this(path, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize) { } public StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize) { // .. } coreclr/src/mscorlib/src/System/IO/StreamReader.csCI example
  • 18. Refactoring tightly coupled class to leverage CI public class Consumer { #region Public methods public void Process() { if (AuthenticationService.Instance.Authenticated()) { var result = ConfigurationService.Instance.GetConfig(); LoggingService.Instance.Log(result); // ... } } #endregion }
  • 19. Refactored class with CI public class Consumer { private readonly IAuthenticationService _authenticationService; private readonly IConfigurationService _configurationService; private readonly ILoggingService _loggingService; public Consumer(IAuthenticationService authenticationService, IConfigurationService configurationService, ILoggingService loggingService) { if (authenticationService == null) throw new ArgumentNullException(nameof(authenticationService)); if (configurationService == null) throw new ArgumentNullException(nameof(configurationService)); if (loggingService == null) throw new ArgumentNullException(nameof(loggingService)); _authenticationService = authenticationService; _configurationService = configurationService; _loggingService = loggingService; } public void Process() { if (_authenticationService.Authenticate()) { var result = _configurationService.GetConfig(); _loggingService.Log(result); } } }
  • 20. DI patterns #2: Property (aka Setter) Injection Best way to initialize a “good Local Default” © Mark Seeman Given the fact it is not mandatory to set a property as opposed to provide dependency to a class constructor, think of PI as a way to describe optional dependencies
  • 21. Example: ASP.NET Core globalization & I8n (custom provider services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("fr") }; options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context => { // Custom request culture logic return new ProviderCultureResult("en"); })); });
  • 22. DI patterns #2: Property (aka Setter) Injection public ICache LocalCache { get; set; } public void Process(IElement element) { if (_authenticationService.Authenticate()) { var config = _configurationService.GetConfig(); _loggingService.Log(config); if (LocalCache?.Contains(element) == true) { //.. } } } // Usage: var consumer = new Consumer(..); consumer.LocalCache = new LocalDbCache();
  • 23. DI patterns #3: Method Injection Think about this dependency as some sort of context for operation (add-in ©) Try to keep methods “pure” since state change between calls may cause unexpected results
  • 24. /// <summary> /// Binds a model specified by <paramref name="parameter"/> using <paramref name="value"/> as the initial value. /// </summary> /// <param name="actionContext">The <see cref="ActionContext"/>.</param> /// <param name="modelBinder">The <see cref="IModelBinder"/>.</param> /// <param name="valueProvider">The <see cref="IValueProvider"/>.</param> /// <param name="parameter">The <see cref="ParameterDescriptor"/></param> /// <param name="metadata">The <see cref="ModelMetadata"/>.</param> /// <param name="value">The initial model value.</param> /// <returns>The result of model binding.</returns> public virtual async Task<ModelBindingResult> BindModelAsync( ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, object value) { // .. } MI example Mvc/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Param eterBinder.cs
  • 25. DI patterns #4: Ambient context Static property or method (accessor) providing a dependency to every module. The context must be an abstraction and the respective property should be writable so we could leverage DI
  • 26. Example: .NET Tracing public class AmbientContext { public void DoTrace() { Trace.Listeners.Add(new ConsoleListener()); Trace.WriteLine("Traced message"); } private class ConsoleListener : TraceListener { public override void Write(string message) { Console.Write("Custom listener message: " + message); } public override void WriteLine(string message) { Console.WriteLine("Custom listener message: " + message); } } }
  • 27. DI patterns #4: Ambient context public class RealDateTimeProvider : IDateTimeProvider { public DateTime Today() { return DateTime.Today; } } public static class DateTimeProvider { private static IDateTimeProvider _currentDateTimeProvider; public static IDateTimeProvider Current { get { return _currentDateTimeProvider ?? Default; } set { _currentDateTimeProvider = value; } } public static IDateTimeProvider Default = new RealDateTimeProvider(); } // Context usage: var today = DateTimeProvider.Current.Today(); // Altering AC if needed: DateTimeProvider.Current = new MockDateTimeProvider();
  • 28. DI antipatterns. #1- Control Freak Class controlling all of its dependencies by explicitly instantiating them Red flag: new keyword all over the code Results in inability to control objects lifetime and being constraint to a current (tightly coupled) implementation Refactoring to interfaces, but still instantiating objects inside class does not result in proper DI
  • 29. DI antipatterns. #2 – Bastard injection (Test-specific) constructor defaulting some of the class dependencies Increases the amount of implicit dependencies Makes choice between constructor ambiguous, can cause issues with IoC containers Result of developers’ attempt to make code testable without full understanding of DI*
  • 30. Example: Ayende Rahien - Reviewing NerdDinner (2009)
  • 31. DI antipatterns. #3 – Constrained construction Require a dependency to have a specific constructor (and throw exception when mandatory configuration is not available) Improper solution for achieving late binding
  • 32. DI antipatterns. #4 – Service Locator Although introduced by Martin Fowler, is considered an anti- pattern: - Hides dependencies - Causes runtime errors instead of compile-time - Amplifies the possibility of introducing breaking changes during maintenance Service Locator is an Anti-Pattern by Mark Seemann http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/ SOLID Encapsulation
  • 33. Fighting Dealing with DI anti-patterns • Decouple logic into separate classes • Extract interfaces/abstract base classes • Investigate object runtime behavior, try to make decision on implementation choosing as late as possible • Defer objects creation to Factories • Don’t forget about created objects lifecycle (dispose etc.) • Monitor coupling (NDepend and other tools) • Think strategy over tactics, don’t over- refactor (o_O)
  • 34. Inversion of Control Inversion of Control (IoC) as a style of programming in which the framework takes the control of the flow instead of your code. IoC is also known as the Hollywood Principle: “Don't call us, we'll call you” NB: has nothing to do with actual dependencies passing
  • 35. Inversion of Control IoC is an attribute of a framework. A library may have or may not have IoC, framework always will. DI helps achieve IoC Martin Fowler - Inversion of Control Containers and the Dependency Injection patte https://www.martinfowler.com/articles/injection.html
  • 36. IoC Example – ASP.NET Core Startup.cs public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit // http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", true) .Build(); var connectionString = config.GetConnectionString("DefaultConnection"); var optionsBuilder = new DbContextOptionsBuilder().UseSqlServer(connectionString); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseStaticFiles(); loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); } }
  • 37. Inversion of Control IoC defers the responsibility of dependencies creation to a higher level code. This way we substitute composition with aggregation and move some of the problems out of the particular class. Ideally this responsibility should be propagated to a single point – so-called Composition Root
  • 38.
  • 39. Inversion of Control IoC (the same as DI and other engineering practices) is not a goal on itself IoC as design principle that targets complexity and helps simplify maintenance of big solutions If it is misused or exaggerated, one should not expect positive effect
  • 40. The most usual IoC offender… … Control Freak/ God Object
  • 41. DI/IoC Containers In real world applications, a single class can have many dependencies, each of which have their own dependencies that forms a large graph. That’s the place where DI container comes to the rescue. A DI container should resolve the dependencies, and this is where the decision of selecting a concrete class for the given abstraction should be made.
  • 42. NB: “DI” vs. “IoC” containers Calling container “DI” have mostly historical roots. Since IoC is a broader term, and also because modern containers support scope management, lifecycle management, calls interception and delayed initialization which does not fit well into DI paradigm, it’s more correct to call them “IoC containers”.
  • 45. “Building an IoC container in 15 lines of code”
  • 46. “Building an IoC container in 15 lines of code” © 2007 Oren Eini aka Ayende Rahien https://ayende.com/blog/2886/building-an-ioc-container-in-15-lines-of-code
  • 47. “Building an IoC container in 15 lines of code” 1) Configuration  2) Lifecycle management 3) Registering service bindings  4) Handling instance activation
  • 49. Which container should I choose? • Should it be cross-platform?
  • 50. Which container should I choose? • Should it be cross-platform? • Single vs. multi-threaded resolving
  • 51. Which container should I choose? • Should it be cross-platform? • Single vs. multi-threaded resolving • Code vs. XML vs. auto- configuration capabilities
  • 52. Which container should I choose? • Should it be cross-platform? • Single vs. multi-threaded resolving • Code vs. XML vs. auto- configuration capabilities • Do you encounter complex scenarios that will require custom objects lifetime management?
  • 53. Which container should I choose? • Should it be cross-platform? • Single vs. multi-threaded resolving • Code vs. XML vs. auto- configuration capabilities • Do you encounter complex scenarios that will require custom objects lifetime management? • Do you need generics/IEnumerable support?
  • 54. Which container should I choose? • Should it be cross-platform? • Single vs. multi-threaded resolving • Code vs. XML vs. auto- configuration capabilities • Do you encounter complex scenarios that will require custom objects lifetime management? • Do you need generics/IEnumerable support? • Will you do complex property/child containers resolving?
  • 55. Which container should I choose? • Should it be cross-platform? • Single vs. multi-threaded resolving • Code vs. XML vs. auto- configuration capabilities • Do you encounter complex scenarios that will require custom objects lifetime management? • Do you need generics/IEnumerable support? • Will you do complex property/child containers resolving? • Interception proxy
  • 56. Which container should I choose? • Should it be cross-platform? • Single vs. multi-threaded resolving • Code vs. XML vs. auto- configuration capabilities • Do you encounter complex scenarios that will require custom objects lifetime management? • Do you need generics/IEnumerable support? • Will you do complex property/child containers resolving? • Interception proxy
  • 58. https://github.com/stebet/DependencyInjectorBenchmarks 0.00 5000.00 10000.00 15000.00 20000.00 25000.00 Direct LightInject SimpleInjector AspNetCore StructureMap Unity Autofac CastleWindsor Mef Ninject IoC Containers performance X86 Legacy JIT X64 Legacy JIT X64 RyuJIT
  • 59. Measure yourself with Benchmark.NET https://github.com/dotnet/BenchmarkDotNet
  • 60.
  • 61.
  • 62. Rule of Thumb The container is used properly when the application is completely unaware of it’s existence.
  • 63. Rule of Thumb The container is used properly when the application is completely unaware of it’s existence.
  • 64. References: • Baharestani Daniel - Mastering Ninject for Dependency Injection (Packt Publishing, 2013) • Seemann Mark - Dependency Injection in .NET (Manning, 2012) • Martin Fowler - Inversion of Control Containers and the Dependency Injection pattern (https://www.martinfowler.com/articles/injection.html) • James Shore - Dependency Injection Demystified (http://www.jamesshore.com/Blog/Dependency-Injection- Demystified.html) • Ayende @ Rahien blog (https://ayende.com) • Sergey Teplyakov blog (http://sergeyteplyakov.blogspot.com) • Eric Lippert - Immutability in C# Part One: Kinds of Immutability (https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/) • Mark Seemann - Service Locator is an Anti-Pattern (http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti- Pattern/) • Daniel Palme - IoC Container Benchmark - Performance comparison • (http://www.palmmedia.de/Blog/2011/8/30/ioc-container-benchmark-performance-comparison, https://github.com/danielpalme/IocPerformance) • Andrey Akinshin – Benchmark.NET (https://github.com/dotnet/BenchmarkDotNet) • RavenDB (https://github.com/ravendb/ravendb) • ASP.NET Core MVC (https://github.com/aspnet/Mvc/) • Core CLR (https://github.com/dotnet/coreclr) • Jeremy Clark - Dependency Injection On-Ramp Pluralsight course (https://app.pluralsight.com/library/courses/dependency-injection-on-ramp/table-of-contents) • John Sonmez - Practical IoC With ASP.NET MVC 4 Pluralsight course (https://app.pluralsight.com/library/courses/ioc-aspdotnet-mvc4/table-of-contents)
  • 65.