SlideShare a Scribd company logo
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)

More Related Content

What's hot

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 Camp
Theo Jungeblut
 
IOC in unity
IOC in unityIOC in unity
IOC in unity
Francesco Garavaglia
 
Clean Code 2
Clean Code 2Clean Code 2
Clean Code 2
Fredrik Wendt
 
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 Injection
Theo 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 Osnabrueck
Theo 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 Lohika
Alex Tumanoff
 
Entity Persistence with JPA
Entity Persistence with JPAEntity Persistence with JPA
Entity Persistence with JPA
Subin Sugunan
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScript
Lilia Sfaxi
 
The Zen of Inversion of Control
The Zen of Inversion of ControlThe Zen of Inversion of Control
The Zen of Inversion of Control
christopherfairbairn
 
Ecom lec4 fall16_jpa
Ecom lec4 fall16_jpaEcom lec4 fall16_jpa
Ecom lec4 fall16_jpa
Zainab Khallouf
 
Java persistence api 2.1
Java persistence api 2.1Java persistence api 2.1
Java persistence api 2.1
Rakesh K. Cherukuri
 
Introduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionIntroduction to Spring's Dependency Injection
Introduction to Spring's Dependency Injection
Richard Paul
 
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
 
JPA For Beginner's
JPA For Beginner'sJPA For Beginner's
JPA For Beginner's
NarayanaMurthy Ganashree
 
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
 

What's hot (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)
 

Viewers also liked

Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
Thibaud 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 architecture
Thomas Jaskula
 
IoC and Mapper in C#
IoC and Mapper in C#IoC and Mapper in C#
IoC and Mapper in C#
Huy Hoàng Phạm
 
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 injection
GetDev.NET
 
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. Шкредов С. — Управление зависимостями в архитектуре. Переход о...CodeFest
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
HAO-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 Practice
Lars-Erik Kindblad
 
SOLID Principles Part 3
SOLID Principles Part 3SOLID Principles Part 3
SOLID Principles Part 3
Maulik Soni
 
Dependency Injection with Unity Container
Dependency Injection with Unity ContainerDependency Injection with Unity Container
Dependency Injection with Unity Container
Mindfire Solutions
 
Inversion of control
Inversion of controlInversion of control
Inversion of control
Emmet 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 Wrong
Paul Armstrong
 
Introduction to SOLID Principles
Introduction to SOLID PrinciplesIntroduction to SOLID Principles
Introduction to SOLID Principles
Ganesh Samarthyam
 
Open Closed Principle kata
Open Closed Principle kataOpen Closed Principle kata
Open Closed Principle kata
Paul 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 Transformation
Eric 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 DDD
Dennis Doomen
 

Viewers also liked (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
 

Similar to Functional Dependency Injection in C#

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
Remo Jansen
 
IOC in Unity
IOC in Unity  IOC in Unity
IOC in Unity
Francesco Garavaglia
 
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 Camp
Theo Jungeblut
 
Automated Discovery of Deserialization Gadget Chains
 Automated Discovery of Deserialization Gadget Chains Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget Chains
Priyanka 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 Code
Naresh Jain
 
Dependency Injection and Autofac
Dependency Injection and AutofacDependency Injection and Autofac
Dependency Injection and Autofac
meghantaylor
 
CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
Prasad Subramanian
 
Designing Testable Software
Designing Testable SoftwareDesigning Testable Software
Designing Testable Software
Omegapoint Academy
 
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
Ugo Matrangolo
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
Caleb Jenkins
 
Ef Poco And Unit Testing
Ef Poco And Unit TestingEf Poco And Unit Testing
Ef Poco And Unit Testing
James Phillips
 
Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsAutomated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget Chains
Priyanka Aash
 
Automated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget ChainsAutomated Discovery of Deserialization Gadget Chains
Automated Discovery of Deserialization Gadget Chains
Priyanka Aash
 
Unit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes CodeUnit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes Code
BlueFish
 
Dependency Inversion Principle
Dependency Inversion PrincipleDependency Inversion Principle
Dependency Inversion Principle
Shahriar Hyder
 
Unit Testing DFC
Unit Testing DFCUnit Testing DFC
Unit Testing DFC
BlueFish
 

Similar to Functional Dependency Injection in C# (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
 

Recently uploaded

AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 

Recently uploaded (20)

AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 

Functional Dependency Injection in C#

  • 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)

Editor's Notes

  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