SlideShare une entreprise Scribd logo
1  sur  42
Dependency Injection 2015
The functional way without IoC container
@tjaskula
Why to talk about ?
IoC container granted from the start.
Developers argue about which framework to chose and not the
problem to solve.
DI vs. IoC
Inversion of Control (IoC) :
Objects don’t create other objects. They get them from outside
Dependency Injection (DI) :
Subset of IoC that means that object creation is done without the object
intervention, usually by a framework component
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
try
{
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
catch (Exception e)
{
// log
}
}
New requirements
Log, Security, Audit, Cache…Cross Cutting Concerns
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
private readonly UnitOfWork _unitOfWork;
private readonly EnrollementNotificationService _notificationService;
private readonly ILogger _logger;
private readonly AuthorizationService _authorizationService;
private readonly CalendarService _calendarService;
private readonly ServiceFoo _serviceFoo;
private readonly ServiceBlah _serviceBlah;
private readonly FactoryFoo _facoFactoryFoo;
private readonly FactoryBlah _factoryBlah;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository,
UnitOfWork unitOfWork,
EnrollementNotificationService notificationService,
ILogger logger,
AuthorizationService authorizationService,
CalendarService calendarService,
ServiceFoo serviceFoo,
ServiceBlah serviceBlah,
FactoryFoo facoFactoryFoo,
FactoryBlah factoryBlah
)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
_unitOfWork = unitOfWork;
_notificationService = notificationService;
_logger = logger;
_authorizationService = authorizationService;
_calendarService = calendarService;
_serviceFoo = serviceFoo;
_serviceBlah = serviceBlah;
_facoFactoryFoo = facoFactoryFoo;
_factoryBlah = factoryBlah;
}
}
public void Handles(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
try
{
_unitOfWork.BeginTransaction();
student.TryEnrollIn(@class);
@class.TryEnroll(student);
…or better… AOP to the rescue
[Logable]
[Authorizable]
[Cachable]
[ExceptionPolicy]
[Blablable]
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Handles(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
try
{
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
catch (Exception e)
{
// log
}
}
Yes, but container can do more !
AOP with interception
var calculator = new Calculator();
var calculatorProxy = Intercept.ThroughProxy<ICalculator>(calculator,
new InterfaceInterceptor(), new[] { new LogBehavior() });
but one must :
• know Dynamic Proxy pattern
• know the difference of Instance and Type Interceptors
• know Interception behaviors
• not forget VIRTUAL keyword on methods
• wire up IoC container correctly
Really ?!!! Is this…
SIMPLE ?
DI flavors
IoC with conventions...
Scan(x =>
{
x.TheCallingAssembly();
x.ExcludeNamespaceContainingType<IEvent>();
x.ExcludeNamespaceContainingType<SearchModel>();
x.ExcludeNamespaceContainingType<AuthenticationService>()
x.ExcludeNamespaceContainingType<DovetailController>();
x.AddAllTypesOf<IDomainMap>();
x.WithDefaultConventions();
DI flavors
IoC with conventions...
Scan(x =>
{
x.TheCallingAssembly();
x.ExcludeNamespaceContainingType<IEvent>();
x.ExcludeNamespaceContainingType<SearchModel>();
x.ExcludeNamespaceContainingType<AuthenticationService>()
x.ExcludeNamespaceContainingType<DovetailController>();
x.AddAllTypesOf<IDomainMap>();
x.WithDefaultConventions();
DI flavors
IoC with manual configuration...
var container = new UnityContainer();
container.RegisterType<IService, Service>(“Service”);
container.RegisterType<IService,ServiceDecorator>(
new InjectionConstructor(new ResolvedParameter(typeof(IS
Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne
c.Resolve<ISubServiceProvider();
));
container.AddNewExtension<DecoratorContainerExtension>();
container.RegisterType<IService, ServiceDecorator>();
DI flavors
IoC with manual configuration...
var container = new UnityContainer();
container.RegisterType<IService, Service>(“Service”);
container.RegisterType<IService,ServiceDecorator>(
new InjectionConstructor(new ResolvedParameter(typeof(IS
Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne
c.Resolve<ISubServiceProvider();
));
container.AddNewExtension<DecoratorContainerExtension>();
container.RegisterType<IService, ServiceDecorator>();
DI flavors
IoC with XML configuration...
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" />
<typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" />
<typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" />
<typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" />
<typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" />
<typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" />
</typeAliases>
<containers>
<container>
<types>
<type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/>
<type type="ILogger" mapTo="DebugLogger" name="debugLogger"/>
<type type="IContext" mapTo="UnityContext">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi
<constructor>
<param name="logger" parameterType="ILogger">
DI flavors
IoC with XML configuration...
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" />
<typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" />
<typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" />
<typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" />
<typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" />
<typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" />
</typeAliases>
<containers>
<container>
<types>
<type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/>
<type type="ILogger" mapTo="DebugLogger" name="debugLogger"/>
<type type="IContext" mapTo="UnityContext">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi
<constructor>
<param name="logger" parameterType="ILogger">
DI flavors
IoC with XML configuration...
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" />
<typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" />
<typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" />
<typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" />
<typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" />
<typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" />
</typeAliases>
<containers>
<container>
<types>
<type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/>
<type type="ILogger" mapTo="DebugLogger" name="debugLogger"/>
<type type="IContext" mapTo="UnityContext">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi
<constructor>
<param name="logger" parameterType="ILogger">
What problem do we try to solve ?
• Decoupling ?
• Testing ?
• Modular Design ?
• Dependencies management ?
Dependencies are bad....
public class EnrollmentCommandHandler
{
public EnrollmentCommandHandler(StudentRepository studentReposit
ClassRepository classReposit
StudentArchiveRepository stu
UnitOfWork unitOfWork,
EnrollementNotificationServi
ILogger logger,
AuthorizationService authori
CalendarService calendarServ
ServiceFoo serviceFoo,
ServiceBlah serviceBlah,
FactoryFoo facoFactoryFoo,
FactoryBlah factoryBlah
Cyclic dependencies are evil....
public class EnrollmentCommandHandler
{
public EnrollmentCommandHandler(StudentRepository studentReposit
ClassRepository classReposit
StudentArchiveRepository stu
UnitOfWork unitOfWork,
EnrollementNotificationServi
ILogger logger,
AuthorizationService authori
CalendarService calendarServ
ServiceFoo serviceFoo,
ServiceBlah serviceBlah,
FactoryFoo facoFactoryFoo,
FactoryBlah factoryBlah
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
}
Code we have....
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
}
Code that matters…
The rest is Plumbing code
Functional way
int Multiply(int a, int b)
{
return a * b;
}
Partial application
Func<int, int> multiplyBy10 = b => Multiply(10, b);
Functional way int a = 3;
int b = a + 7;
int c = b * 10;
Composition
Func<int, int> calcCFromA = a => CalcC(CalcB(a));
int CalcCFromA(int a, int b, int c)
{
return (a + 7) * 10;
}
int CalcCFromA(int a, int b, int c)
{
return CalcC(CalcB(a));
}
let calcCFromA = calcB >> calcC
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
}
Refactor this…
public void Enroll(StudentRepository studentRepository, ClassRepository classRepository,
StudentEnrollCommand command)
{
var student = studentRepository.GetById(command.StudentId);
var @class = classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
to this…
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
Action<StudentEnrollCommand> studentEnrollPipeline = c =>
handlers.Enroll(studentRepository, classRepository, c);
Bootstrap in one place…
[HttpPost]
public void Enroll(EnrollmentRendering r)
{
_handlers.Dispatch(r.ToCommand());
}
Handle in another…
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
Action<StudentEnrollCommand> studentEnrollPipeline
= c =>
handlers.Log(c, c1 =>
handlers.Enroll(studentRepository, classRepository, c1));
Want to log ?
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
Action<StudentEnrollCommand> studentEnrollPipeline
= c =>
handlers.Audit(c, c1 =>
handlers.Log(c1, c2 =>
handlers.Enroll(studentRepository, classRepository, c2));
Audit ?
var lifeTime = new LifeTime();
Func<StudentRepository> studentRepositoryFactory = () => new StudentRepository();
Func<ClassRepository> classRepositoryFactory = () => new ClassRepository();
Action<StudentEnrollCommand> studentEnrollPipeline
= c =>
handlers.Audit(c, c1 =>
handlers.Log(c1, c2 =>
handlers.Enroll(lifeTime.PerThread(studentRepositoryFactory),
lifeTime.PerThread(classRepositoryFactory), c2));
Lifetime management ?
public TResult PerThread<TResult>(Func<TResult> dependencyFactory) where TResult : class
{
ThreadLocal<object> threadLocal = new ThreadLocal<object>(dependencyFactory);
threadLocal = _dependencies.GetOrAdd(typeof(TResult), threadLocal);
return (TResult)threadLocal.Value;
}
Easy !
Why to do it ?
• 99% of time you don’t have a problem for IoC container
• IoC makes easier things you shouldn’t be doing anyway
• Feel the pain and think
To many dependencies ?
• You have another serious problem
To take away
• Be stupid! Don’t waste your brain on complicated code
• Don’t waste your time to understand Rube Goldberg machines
• Simplicity
• Readability
Understand your problem before
using a tool
References
• Greg Young (8 lines of code InfoQ
http://www.infoq.com/presentations/8-lines-code-refactoring)

Contenu connexe

Tendances

Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language Mahika Tutorials
 
Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group Theo Jungeblut
 
Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code CampCut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code CampTheo Jungeblut
 
Hibernate complete Training
Hibernate complete TrainingHibernate complete Training
Hibernate complete Trainingsourabh aggarwal
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency InjectionTheo Jungeblut
 
Cut your Dependencies with Dependency Injection - .NET User Group Osnabrueck
Cut your Dependencies with Dependency Injection - .NET User Group OsnabrueckCut your Dependencies with Dependency Injection - .NET User Group Osnabrueck
Cut your Dependencies with Dependency Injection - .NET User Group OsnabrueckTheo Jungeblut
 
Dependency injection with unity 2.0 Dmytro Mindra Lohika
Dependency injection with unity 2.0 Dmytro Mindra LohikaDependency injection with unity 2.0 Dmytro Mindra Lohika
Dependency injection with unity 2.0 Dmytro Mindra LohikaAlex Tumanoff
 
Entity Persistence with JPA
Entity Persistence with JPAEntity Persistence with JPA
Entity Persistence with JPASubin Sugunan
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScriptLilia Sfaxi
 
Introduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionIntroduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionRichard Paul
 
Java Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By StepJava Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By StepGuo Albert
 
Java persistence api
Java persistence api Java persistence api
Java persistence api Luis Goldster
 
Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)
Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)
Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)Theo Jungeblut
 

Tendances (19)

Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language
 
Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group
 
Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code CampCut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
 
IOC in unity
IOC in unityIOC in unity
IOC in unity
 
Clean Code 2
Clean Code 2Clean Code 2
Clean Code 2
 
Hibernate complete Training
Hibernate complete TrainingHibernate complete Training
Hibernate complete Training
 
Clean Code II - Dependency Injection
Clean Code II - Dependency InjectionClean Code II - Dependency Injection
Clean Code II - Dependency Injection
 
Cut your Dependencies with Dependency Injection - .NET User Group Osnabrueck
Cut your Dependencies with Dependency Injection - .NET User Group OsnabrueckCut your Dependencies with Dependency Injection - .NET User Group Osnabrueck
Cut your Dependencies with Dependency Injection - .NET User Group Osnabrueck
 
Dependency injection with unity 2.0 Dmytro Mindra Lohika
Dependency injection with unity 2.0 Dmytro Mindra LohikaDependency injection with unity 2.0 Dmytro Mindra Lohika
Dependency injection with unity 2.0 Dmytro Mindra Lohika
 
Entity Persistence with JPA
Entity Persistence with JPAEntity Persistence with JPA
Entity Persistence with JPA
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScript
 
The Zen of Inversion of Control
The Zen of Inversion of ControlThe Zen of Inversion of Control
The Zen of Inversion of Control
 
Ecom lec4 fall16_jpa
Ecom lec4 fall16_jpaEcom lec4 fall16_jpa
Ecom lec4 fall16_jpa
 
Java persistence api 2.1
Java persistence api 2.1Java persistence api 2.1
Java persistence api 2.1
 
Introduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionIntroduction to Spring's Dependency Injection
Introduction to Spring's Dependency Injection
 
Java Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By StepJava Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By Step
 
JPA For Beginner's
JPA For Beginner'sJPA For Beginner's
JPA For Beginner's
 
Java persistence api
Java persistence api Java persistence api
Java persistence api
 
Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)
Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)
Clean Code II - Dependency Injection at SoCal Code Camp San Diego (07/27/2013)
 

En vedette

Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right wayThibaud Desodt
 
CQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureCQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureThomas Jaskula
 
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...Svetlin Nakov
 
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.3Fabien Potencier
 
Dependency injection
Dependency injectionDependency injection
Dependency injectionGetDev.NET
 
CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...
CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...
CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...CodeFest
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in LaravelHAO-WEN ZHANG
 
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 PracticeLars-Erik Kindblad
 
SOLID Principles Part 3
SOLID Principles Part 3SOLID Principles Part 3
SOLID Principles Part 3Maulik Soni
 
Dependency Injection with Unity Container
Dependency Injection with Unity ContainerDependency Injection with Unity Container
Dependency Injection with Unity ContainerMindfire Solutions
 
Inversion of control
Inversion of controlInversion of control
Inversion of controlEmmet Irish
 
Do you know Dependency Injection ?
Do you know Dependency Injection ?Do you know Dependency Injection ?
Do you know Dependency Injection ?Masayuki IZUMI
 
You're Still Doing It Wrong
You're Still Doing It WrongYou're Still Doing It Wrong
You're Still Doing It WrongPaul Armstrong
 
Introduction to SOLID Principles
Introduction to SOLID PrinciplesIntroduction to SOLID Principles
Introduction to SOLID PrinciplesGanesh Samarthyam
 
Open Closed Principle kata
Open Closed Principle kataOpen Closed Principle kata
Open Closed Principle kataPaul Blundell
 
Taste-of-Summit: Discover the Foundations of Digital Transformation
Taste-of-Summit: Discover the Foundations of Digital TransformationTaste-of-Summit: Discover the Foundations of Digital Transformation
Taste-of-Summit: Discover the Foundations of Digital TransformationEric D. Schabell
 
CQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDDCQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDDDennis Doomen
 

En vedette (20)

Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
CQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureCQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architecture
 
IoC and Mapper in C#
IoC and Mapper in C#IoC and Mapper in C#
IoC and Mapper in C#
 
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
Architectural Patterns and Software Architectures: Client-Server, Multi-Tier,...
 
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
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
Dependency Injection Andrey Stadnik(enemis)
Dependency Injection Andrey Stadnik(enemis)Dependency Injection Andrey Stadnik(enemis)
Dependency Injection Andrey Stadnik(enemis)
 
CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...
CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...
CodeFest 2014. Шкредов С. — Управление зависимостями в архитектуре. Переход о...
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
 
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
 
SOLID Principles Part 3
SOLID Principles Part 3SOLID Principles Part 3
SOLID Principles Part 3
 
Dependency Injection with Unity Container
Dependency Injection with Unity ContainerDependency Injection with Unity Container
Dependency Injection with Unity Container
 
Inversion of control
Inversion of controlInversion of control
Inversion of control
 
Do you know Dependency Injection ?
Do you know Dependency Injection ?Do you know Dependency Injection ?
Do you know Dependency Injection ?
 
You're Still Doing It Wrong
You're Still Doing It WrongYou're Still Doing It Wrong
You're Still Doing It Wrong
 
Introduction to SOLID Principles
Introduction to SOLID PrinciplesIntroduction to SOLID Principles
Introduction to SOLID Principles
 
Open Closed Principle kata
Open Closed Principle kataOpen Closed Principle kata
Open Closed Principle kata
 
Taste-of-Summit: Discover the Foundations of Digital Transformation
Taste-of-Summit: Discover the Foundations of Digital TransformationTaste-of-Summit: Discover the Foundations of Digital Transformation
Taste-of-Summit: Discover the Foundations of Digital Transformation
 
CQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDDCQRS and Event Sourcing, An Alternative Architecture for DDD
CQRS and Event Sourcing, An Alternative Architecture for DDD
 

Similaire à Dependency Injection without IoC

Dependency Inversion in large-scale TypeScript applications with InversifyJS
Dependency Inversion in large-scale TypeScript applications with InversifyJSDependency Inversion in large-scale TypeScript applications with InversifyJS
Dependency Inversion in large-scale TypeScript applications with InversifyJSRemo Jansen
 
Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...
Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...
Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...Theo Jungeblut
 
Clean Code Part II - Dependency Injection at SoCal Code Camp
Clean Code Part II - Dependency Injection at SoCal Code CampClean Code Part II - Dependency Injection at SoCal Code Camp
Clean Code Part II - Dependency Injection at SoCal Code CampTheo Jungeblut
 
Automated Discovery of Deserialization Gadget Chains
 Automated Discovery of Deserialization Gadget Chains Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsPriyanka Aash
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJiayun Zhou
 
Managed Extensibility Framework (MEF)
Managed Extensibility Framework (MEF)Managed Extensibility Framework (MEF)
Managed Extensibility Framework (MEF)Mohamed Meligy
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy CodeNaresh Jain
 
Dependency Injection and Autofac
Dependency Injection and AutofacDependency Injection and Autofac
Dependency Injection and Autofacmeghantaylor
 
Dsug 05 02-15 - ScalDI - lightweight DI in Scala
Dsug 05 02-15 - ScalDI - lightweight DI in ScalaDsug 05 02-15 - ScalDI - lightweight DI in Scala
Dsug 05 02-15 - ScalDI - lightweight DI in ScalaUgo Matrangolo
 
Ef Poco And Unit Testing
Ef Poco And Unit TestingEf Poco And Unit Testing
Ef Poco And Unit TestingJames Phillips
 
Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsAutomated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsPriyanka Aash
 
Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsAutomated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsPriyanka Aash
 
Unit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes CodeUnit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes CodeBlueFish
 
Dependency Inversion Principle
Dependency Inversion PrincipleDependency Inversion Principle
Dependency Inversion PrincipleShahriar Hyder
 
Unit Testing DFC
Unit Testing DFCUnit Testing DFC
Unit Testing DFCBlueFish
 

Similaire à Dependency Injection without IoC (20)

Dependency Inversion in large-scale TypeScript applications with InversifyJS
Dependency Inversion in large-scale TypeScript applications with InversifyJSDependency Inversion in large-scale TypeScript applications with InversifyJS
Dependency Inversion in large-scale TypeScript applications with InversifyJS
 
IOC in Unity
IOC in Unity  IOC in Unity
IOC in Unity
 
Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...
Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...
Cut your Dependencies with - Dependency Injection for South Bay.NET User Grou...
 
Clean Code Part II - Dependency Injection at SoCal Code Camp
Clean Code Part II - Dependency Injection at SoCal Code CampClean Code Part II - Dependency Injection at SoCal Code Camp
Clean Code Part II - Dependency Injection at SoCal Code Camp
 
Automated Discovery of Deserialization Gadget Chains
 Automated Discovery of Deserialization Gadget Chains Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget Chains
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
 
Swiz DAO
Swiz DAOSwiz DAO
Swiz DAO
 
Managed Extensibility Framework (MEF)
Managed Extensibility Framework (MEF)Managed Extensibility Framework (MEF)
Managed Extensibility Framework (MEF)
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Dependency Injection and Autofac
Dependency Injection and AutofacDependency Injection and Autofac
Dependency Injection and Autofac
 
CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
 
Designing Testable Software
Designing Testable SoftwareDesigning Testable Software
Designing Testable Software
 
Dsug 05 02-15 - ScalDI - lightweight DI in Scala
Dsug 05 02-15 - ScalDI - lightweight DI in ScalaDsug 05 02-15 - ScalDI - lightweight DI in Scala
Dsug 05 02-15 - ScalDI - lightweight DI in Scala
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
 
Ef Poco And Unit Testing
Ef Poco And Unit TestingEf Poco And Unit Testing
Ef Poco And Unit Testing
 
Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsAutomated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget Chains
 
Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsAutomated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget Chains
 
Unit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes CodeUnit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes Code
 
Dependency Inversion Principle
Dependency Inversion PrincipleDependency Inversion Principle
Dependency Inversion Principle
 
Unit Testing DFC
Unit Testing DFCUnit Testing DFC
Unit Testing DFC
 

Dernier

Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
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
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
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
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
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
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

Dernier (20)

Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
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
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
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...
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
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
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 

Dependency Injection without IoC

  • 1. Dependency Injection 2015 The functional way without IoC container @tjaskula
  • 2. Why to talk about ? IoC container granted from the start. Developers argue about which framework to chose and not the problem to solve.
  • 3. DI vs. IoC Inversion of Control (IoC) : Objects don’t create other objects. They get them from outside Dependency Injection (DI) : Subset of IoC that means that object creation is done without the object intervention, usually by a framework component
  • 4. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); try { student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } catch (Exception e) { // log } }
  • 5. New requirements Log, Security, Audit, Cache…Cross Cutting Concerns
  • 6. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; private readonly UnitOfWork _unitOfWork; private readonly EnrollementNotificationService _notificationService; private readonly ILogger _logger; private readonly AuthorizationService _authorizationService; private readonly CalendarService _calendarService; private readonly ServiceFoo _serviceFoo; private readonly ServiceBlah _serviceBlah; private readonly FactoryFoo _facoFactoryFoo; private readonly FactoryBlah _factoryBlah; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository, UnitOfWork unitOfWork, EnrollementNotificationService notificationService, ILogger logger, AuthorizationService authorizationService, CalendarService calendarService, ServiceFoo serviceFoo, ServiceBlah serviceBlah, FactoryFoo facoFactoryFoo, FactoryBlah factoryBlah ) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; _unitOfWork = unitOfWork; _notificationService = notificationService; _logger = logger; _authorizationService = authorizationService; _calendarService = calendarService; _serviceFoo = serviceFoo; _serviceBlah = serviceBlah; _facoFactoryFoo = facoFactoryFoo; _factoryBlah = factoryBlah; } } public void Handles(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); try { _unitOfWork.BeginTransaction(); student.TryEnrollIn(@class); @class.TryEnroll(student);
  • 7. …or better… AOP to the rescue
  • 8. [Logable] [Authorizable] [Cachable] [ExceptionPolicy] [Blablable] public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Handles(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); try { student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } catch (Exception e) { // log } }
  • 9. Yes, but container can do more !
  • 10. AOP with interception var calculator = new Calculator(); var calculatorProxy = Intercept.ThroughProxy<ICalculator>(calculator, new InterfaceInterceptor(), new[] { new LogBehavior() });
  • 11. but one must : • know Dynamic Proxy pattern • know the difference of Instance and Type Interceptors • know Interception behaviors • not forget VIRTUAL keyword on methods • wire up IoC container correctly
  • 12. Really ?!!! Is this… SIMPLE ?
  • 13.
  • 14. DI flavors IoC with conventions... Scan(x => { x.TheCallingAssembly(); x.ExcludeNamespaceContainingType<IEvent>(); x.ExcludeNamespaceContainingType<SearchModel>(); x.ExcludeNamespaceContainingType<AuthenticationService>() x.ExcludeNamespaceContainingType<DovetailController>(); x.AddAllTypesOf<IDomainMap>(); x.WithDefaultConventions();
  • 15. DI flavors IoC with conventions... Scan(x => { x.TheCallingAssembly(); x.ExcludeNamespaceContainingType<IEvent>(); x.ExcludeNamespaceContainingType<SearchModel>(); x.ExcludeNamespaceContainingType<AuthenticationService>() x.ExcludeNamespaceContainingType<DovetailController>(); x.AddAllTypesOf<IDomainMap>(); x.WithDefaultConventions();
  • 16. DI flavors IoC with manual configuration... var container = new UnityContainer(); container.RegisterType<IService, Service>(“Service”); container.RegisterType<IService,ServiceDecorator>( new InjectionConstructor(new ResolvedParameter(typeof(IS Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne c.Resolve<ISubServiceProvider(); )); container.AddNewExtension<DecoratorContainerExtension>(); container.RegisterType<IService, ServiceDecorator>();
  • 17. DI flavors IoC with manual configuration... var container = new UnityContainer(); container.RegisterType<IService, Service>(“Service”); container.RegisterType<IService,ServiceDecorator>( new InjectionConstructor(new ResolvedParameter(typeof(IS Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne c.Resolve<ISubServiceProvider(); )); container.AddNewExtension<DecoratorContainerExtension>(); container.RegisterType<IService, ServiceDecorator>();
  • 18. DI flavors IoC with XML configuration... <unity> <typeAliases> <typeAlias alias="string" type="System.String, mscorlib" /> <typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" /> <typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" /> <typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" /> <typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" /> <typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" /> <typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" /> </typeAliases> <containers> <container> <types> <type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/> <type type="ILogger" mapTo="DebugLogger" name="debugLogger"/> <type type="IContext" mapTo="UnityContext"> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi <constructor> <param name="logger" parameterType="ILogger">
  • 19. DI flavors IoC with XML configuration... <unity> <typeAliases> <typeAlias alias="string" type="System.String, mscorlib" /> <typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" /> <typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" /> <typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" /> <typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" /> <typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" /> <typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" /> </typeAliases> <containers> <container> <types> <type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/> <type type="ILogger" mapTo="DebugLogger" name="debugLogger"/> <type type="IContext" mapTo="UnityContext"> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi <constructor> <param name="logger" parameterType="ILogger">
  • 20. DI flavors IoC with XML configuration... <unity> <typeAliases> <typeAlias alias="string" type="System.String, mscorlib" /> <typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" /> <typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" /> <typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" /> <typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" /> <typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" /> <typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" /> </typeAliases> <containers> <container> <types> <type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/> <type type="ILogger" mapTo="DebugLogger" name="debugLogger"/> <type type="IContext" mapTo="UnityContext"> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi <constructor> <param name="logger" parameterType="ILogger">
  • 21. What problem do we try to solve ? • Decoupling ? • Testing ? • Modular Design ? • Dependencies management ?
  • 22. Dependencies are bad.... public class EnrollmentCommandHandler { public EnrollmentCommandHandler(StudentRepository studentReposit ClassRepository classReposit StudentArchiveRepository stu UnitOfWork unitOfWork, EnrollementNotificationServi ILogger logger, AuthorizationService authori CalendarService calendarServ ServiceFoo serviceFoo, ServiceBlah serviceBlah, FactoryFoo facoFactoryFoo, FactoryBlah factoryBlah
  • 23. Cyclic dependencies are evil.... public class EnrollmentCommandHandler { public EnrollmentCommandHandler(StudentRepository studentReposit ClassRepository classReposit StudentArchiveRepository stu UnitOfWork unitOfWork, EnrollementNotificationServi ILogger logger, AuthorizationService authori CalendarService calendarServ ServiceFoo serviceFoo, ServiceBlah serviceBlah, FactoryFoo facoFactoryFoo, FactoryBlah factoryBlah
  • 24. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } } Code we have....
  • 25. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } } Code that matters…
  • 26. The rest is Plumbing code
  • 27. Functional way int Multiply(int a, int b) { return a * b; } Partial application Func<int, int> multiplyBy10 = b => Multiply(10, b);
  • 28. Functional way int a = 3; int b = a + 7; int c = b * 10; Composition Func<int, int> calcCFromA = a => CalcC(CalcB(a)); int CalcCFromA(int a, int b, int c) { return (a + 7) * 10; } int CalcCFromA(int a, int b, int c) { return CalcC(CalcB(a)); } let calcCFromA = calcB >> calcC
  • 29. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } } Refactor this…
  • 30. public void Enroll(StudentRepository studentRepository, ClassRepository classRepository, StudentEnrollCommand command) { var student = studentRepository.GetById(command.StudentId); var @class = classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } to this…
  • 31. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); Action<StudentEnrollCommand> studentEnrollPipeline = c => handlers.Enroll(studentRepository, classRepository, c); Bootstrap in one place…
  • 32. [HttpPost] public void Enroll(EnrollmentRendering r) { _handlers.Dispatch(r.ToCommand()); } Handle in another…
  • 33. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); Action<StudentEnrollCommand> studentEnrollPipeline = c => handlers.Log(c, c1 => handlers.Enroll(studentRepository, classRepository, c1)); Want to log ?
  • 34. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); Action<StudentEnrollCommand> studentEnrollPipeline = c => handlers.Audit(c, c1 => handlers.Log(c1, c2 => handlers.Enroll(studentRepository, classRepository, c2)); Audit ?
  • 35. var lifeTime = new LifeTime(); Func<StudentRepository> studentRepositoryFactory = () => new StudentRepository(); Func<ClassRepository> classRepositoryFactory = () => new ClassRepository(); Action<StudentEnrollCommand> studentEnrollPipeline = c => handlers.Audit(c, c1 => handlers.Log(c1, c2 => handlers.Enroll(lifeTime.PerThread(studentRepositoryFactory), lifeTime.PerThread(classRepositoryFactory), c2)); Lifetime management ?
  • 36. public TResult PerThread<TResult>(Func<TResult> dependencyFactory) where TResult : class { ThreadLocal<object> threadLocal = new ThreadLocal<object>(dependencyFactory); threadLocal = _dependencies.GetOrAdd(typeof(TResult), threadLocal); return (TResult)threadLocal.Value; } Easy !
  • 37. Why to do it ? • 99% of time you don’t have a problem for IoC container • IoC makes easier things you shouldn’t be doing anyway • Feel the pain and think
  • 38. To many dependencies ? • You have another serious problem
  • 39. To take away • Be stupid! Don’t waste your brain on complicated code • Don’t waste your time to understand Rube Goldberg machines • Simplicity • Readability
  • 40. Understand your problem before using a tool
  • 41.
  • 42. References • Greg Young (8 lines of code InfoQ http://www.infoq.com/presentations/8-lines-code-refactoring)

Notes de l'éditeur

  1. My talk about DI containers with Olivier Spinelli several years ago at ALT.NET meetup. Now, this is where I am. But before looking why, let's see a context.
  2. We don't even question if IoC container is needed because nowadays this is considered granted. We argue between containers and theirs features rather than a correct application design.
  3. Can I explain it to junior developer ? Do you want to not hire developers because we don't have 2 years of teaching a framework ?
  4. How many developpers do you know that knows Rube Goldberg machine ? What to do if there is a bug in a framework ? You send an email to the group and pray
  5. What kills simplicity is that sometimes Rube Goldberg machine stops working and by definition you don't understand Rube Goldberg machine