SlideShare a Scribd company logo
1 of 62
Functional Programming in C#
NCrafts 21-22 May, Paris 2015
@tjaskula
What is functional programming ?
• Functions as building blocks
• Function returns values only based on the passed input
• Recursion
• HOF (Higher Order Functions)
• Creation of anonymous functions, in-line, lambda expressions
• Closures
• Immutability
What REALY is FP ?
“Natural way of telling the computer what it should do, by
describing properties of a given problem in a concise language”
Programmers responsibility in FP ?
Specify functions to describe a given set of problems
Object Oriented Programming
• Encapsulation
• Combining data and behavior into classes and objects
• Modeling Real-World
Relationship FP to OOP
• No silver bullet
• Programmer needs to understand different techniques
Why to talk about ?
• Concurrency programming models
• Writing software it’s a complex process
• Managing side effects
Part 1 – Make it simple
Composing dependencies
The OOP way
IoC container granted from the start.
Developers argue about which framework to chose and not the
problem to solve.
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)
{
return (a + 7) * 10;
}
int CalcCFromA(int a)
{
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();
var pipeline = c =>
handlers.Enroll(studentRepository, classRepository, c);
Bootstrap in one place…
_handlers.Dispatch(new StudentEnrollCommand(1));
=
pipeline(new StudentEnrollCommand(1));
Handle in another…
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
var pipeline
= c =>
handlers.Log(c, c1 =>
handlers.Enroll(studentRepository, classRepository, c1));
Want to log ?
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
var studentEnrollPipeline
= c =>
handlers.Audit(c, c1 =>
handlers.Log(c1, c2 =>
handlers.Enroll(studentRepository,classRepository, c2));
Audit ?
var lifeTime = new LifeTime();
var studentRepositoryFactory = () => new StudentRepository();
var classRepositoryFactory = () => new ClassRepository();
var studentEnrollPipeline
= c =>
handlers.Audit(c, c1 =>
handlers.Log(c1, c2 =>
handlers.Enroll(lifeTime.PerThread(studentRepositoryFactory),
lifeTime.PerThread(classRepositoryFactory), c2));
Lifetime management ?
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
Is this…
SIMPLE ?
Is is just pure C# code
Part 2 – Control complexity
Composition strikes again…but in different shape
Writing a program using functions
How to order sequence of functions ?
ParseCopyright(string text) { return text + “©” }
ParseAppendix(string text) { return text.Remove(“APPENDIX”); }
Solution
By composing them
ParseCopyright(ParseAppendix(text));
But this can fail
ParseAppendix function may throw an exception
Solution
Return two kind of things from ParseAppendix function
string string
Instead of Let’s allow
string
string
Error
or
But function can return one thing
And only one thing
Solution
Put in in the box
string ParseResult
What happens to this now ?
ParseCopyright(ParseAppendix(text));
string ParseResultParseAppendix ParseCopyright
is success
Solution
Let’s have a special “link”/”connect”/”compose” function
string ParseResultParseAppendix ParseCopyrightstring
Error
Connect
What we have seen is a…
M***D
Demo
Composition
Composition is the key to controlling complexity in software.
“In our study of program design, we have seen that expert
programmers control the complexity of their designs with the
same general techniques used by designers of all complex
systems. They combine primitive elements to form
compound objects, they abstract compound objects to
form higher-level building blocks, and they preserve
modularity by adopting appropriate large-scale views of system
structure.”
Should I do functional programming
in C# ?
To take away
• Be stupid! Don’t waste your brain on complicated code
• Don’t waste your time to understand Rube Goldberg machines
• Simplicity. Write only the code that matters.
• Readability
• Less bugs
Questions ?
Thanks

More Related Content

What's hot

Tech io spa_angularjs_20130814_v0.9.5
Tech io spa_angularjs_20130814_v0.9.5Tech io spa_angularjs_20130814_v0.9.5
Tech io spa_angularjs_20130814_v0.9.5Ganesh Kondal
 
Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language Mahika Tutorials
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right wayThibaud Desodt
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Jonas Follesø
 
Introduction au Web
Introduction au WebIntroduction au Web
Introduction au WebLilia Sfaxi
 
Behaviour Driven Development V 0.1
Behaviour Driven Development V 0.1Behaviour Driven Development V 0.1
Behaviour Driven Development V 0.1willmation
 
Poco Es Mucho: WCF, EF, and Class Design
Poco Es Mucho: WCF, EF, and Class DesignPoco Es Mucho: WCF, EF, and Class Design
Poco Es Mucho: WCF, EF, and Class DesignJames Phillips
 
Hibernate complete Training
Hibernate complete TrainingHibernate complete Training
Hibernate complete Trainingsourabh aggarwal
 
Unit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes CodeUnit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes CodeBlueFish
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Darwin Biler
 
Bridging the communication Gap & Continuous Delivery
Bridging the communication Gap & Continuous DeliveryBridging the communication Gap & Continuous Delivery
Bridging the communication Gap & Continuous Deliverymasoodjan
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design PatternsLilia Sfaxi
 
Dependency Injection with Unity Container
Dependency Injection with Unity ContainerDependency Injection with Unity Container
Dependency Injection with Unity ContainerMindfire Solutions
 
Design Patterns in iOS
Design Patterns in iOSDesign Patterns in iOS
Design Patterns in iOSYi-Shou Chen
 

What's hot (20)

Deployment
DeploymentDeployment
Deployment
 
Tech io spa_angularjs_20130814_v0.9.5
Tech io spa_angularjs_20130814_v0.9.5Tech io spa_angularjs_20130814_v0.9.5
Tech io spa_angularjs_20130814_v0.9.5
 
Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language Spring FrameWork Tutorials Java Language
Spring FrameWork Tutorials Java Language
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008
 
CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
 
Introduction au Web
Introduction au WebIntroduction au Web
Introduction au Web
 
Behaviour Driven Development V 0.1
Behaviour Driven Development V 0.1Behaviour Driven Development V 0.1
Behaviour Driven Development V 0.1
 
Poco Es Mucho: WCF, EF, and Class Design
Poco Es Mucho: WCF, EF, and Class DesignPoco Es Mucho: WCF, EF, and Class Design
Poco Es Mucho: WCF, EF, and Class Design
 
Hibernate complete Training
Hibernate complete TrainingHibernate complete Training
Hibernate complete Training
 
Unit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes CodeUnit Testing Documentum Foundation Classes Code
Unit Testing Documentum Foundation Classes Code
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4
 
Bridging the communication Gap & Continuous Delivery
Bridging the communication Gap & Continuous DeliveryBridging the communication Gap & Continuous Delivery
Bridging the communication Gap & Continuous Delivery
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Java persistence api 2.1
Java persistence api 2.1Java persistence api 2.1
Java persistence api 2.1
 
The Zen of Inversion of Control
The Zen of Inversion of ControlThe Zen of Inversion of Control
The Zen of Inversion of Control
 
JPA For Beginner's
JPA For Beginner'sJPA For Beginner's
JPA For Beginner's
 
Dependency Injection with Unity Container
Dependency Injection with Unity ContainerDependency Injection with Unity Container
Dependency Injection with Unity Container
 
Design Patterns in iOS
Design Patterns in iOSDesign Patterns in iOS
Design Patterns in iOS
 
Spring survey
Spring surveySpring survey
Spring survey
 

Viewers also liked

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
 
Leveraging more then DDD Lite in the startup project
Leveraging more then DDD Lite in the startup projectLeveraging more then DDD Lite in the startup project
Leveraging more then DDD Lite in the startup projectThomas Jaskula
 
Rx- Reactive Extensions for .NET
Rx- Reactive Extensions for .NETRx- Reactive Extensions for .NET
Rx- Reactive Extensions for .NETJakub Malý
 
What is "Domain Driven Design" and what can you expect from it?
What is "Domain Driven Design" and what can you expect from it?What is "Domain Driven Design" and what can you expect from it?
What is "Domain Driven Design" and what can you expect from it?Tom Janssens
 
A Quick Intro to ReactiveX
A Quick Intro to ReactiveXA Quick Intro to ReactiveX
A Quick Intro to ReactiveXTroy Miles
 
Common ddd pitfalls
Common ddd pitfallsCommon ddd pitfalls
Common ddd pitfallsTom Janssens
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 
Domain-driven design - tactical patterns
Domain-driven design - tactical patternsDomain-driven design - tactical patterns
Domain-driven design - tactical patternsTom Janssens
 
Functional Programming in C# and F#
Functional Programming in C# and F#Functional Programming in C# and F#
Functional Programming in C# and F#Alfonso Garcia-Caro
 
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...Wes McKinney
 
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
 
Why functional programming in C# & F#
Why functional programming in C# & F#Why functional programming in C# & F#
Why functional programming in C# & F#Riccardo Terrell
 

Viewers also liked (18)

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
 
Leveraging more then DDD Lite in the startup project
Leveraging more then DDD Lite in the startup projectLeveraging more then DDD Lite in the startup project
Leveraging more then DDD Lite in the startup project
 
Getting better
Getting betterGetting better
Getting better
 
Rx- Reactive Extensions for .NET
Rx- Reactive Extensions for .NETRx- Reactive Extensions for .NET
Rx- Reactive Extensions for .NET
 
What is "Domain Driven Design" and what can you expect from it?
What is "Domain Driven Design" and what can you expect from it?What is "Domain Driven Design" and what can you expect from it?
What is "Domain Driven Design" and what can you expect from it?
 
A Quick Intro to ReactiveX
A Quick Intro to ReactiveXA Quick Intro to ReactiveX
A Quick Intro to ReactiveX
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Common ddd pitfalls
Common ddd pitfallsCommon ddd pitfalls
Common ddd pitfalls
 
Selling ddd
Selling dddSelling ddd
Selling ddd
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
Domain-driven design - tactical patterns
Domain-driven design - tactical patternsDomain-driven design - tactical patterns
Domain-driven design - tactical patterns
 
Functional Programming with C#
Functional Programming with C#Functional Programming with C#
Functional Programming with C#
 
Functional Programming in C# and F#
Functional Programming in C# and F#Functional Programming in C# and F#
Functional Programming in C# and F#
 
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...
 
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
 
Why functional programming in C# & F#
Why functional programming in C# & F#Why functional programming in C# & F#
Why functional programming in C# & F#
 

Similar to Functional programming in C#

Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDiego Lewin
 
Hibernate presentation
Hibernate presentationHibernate presentation
Hibernate presentationLuis Goldster
 
Dependency injection in CakePHP
Dependency injection in CakePHPDependency injection in CakePHP
Dependency injection in CakePHPmarkstory
 
Example Of Import Java
Example Of Import JavaExample Of Import Java
Example Of Import JavaMelody Rios
 
The Spring Framework: A brief introduction to Inversion of Control
The Spring Framework:A brief introduction toInversion of ControlThe Spring Framework:A brief introduction toInversion of Control
The Spring Framework: A brief introduction to Inversion of ControlVisualBee.com
 
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Miguel Gallardo
 
O365 Saturday - Deepdive SharePoint Client Side Rendering
O365 Saturday - Deepdive SharePoint Client Side RenderingO365 Saturday - Deepdive SharePoint Client Side Rendering
O365 Saturday - Deepdive SharePoint Client Side RenderingRiwut Libinuko
 
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
 
...and thus your forms automagically disappeared
...and thus your forms automagically disappeared...and thus your forms automagically disappeared
...and thus your forms automagically disappearedLuc Bors
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsSalesforce Developers
 
CommercialSystemsBahman.ppt
CommercialSystemsBahman.pptCommercialSystemsBahman.ppt
CommercialSystemsBahman.pptKalsoomTahir2
 
Grails patterns and practices
Grails patterns and practicesGrails patterns and practices
Grails patterns and practicespaulbowler
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09Daniel Bryant
 
ARabia hossain project report.pdf
ARabia hossain project report.pdfARabia hossain project report.pdf
ARabia hossain project report.pdfArabiaHossain
 
Il 09 T3 William Spreitzer
Il 09 T3 William SpreitzerIl 09 T3 William Spreitzer
Il 09 T3 William Spreitzerwspreitzer
 
javascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.pptjavascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.pptLalith86
 
Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Codejameshalsall
 

Similar to Functional programming in C# (20)

Android meetup
Android meetupAndroid meetup
Android meetup
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
 
Tdd,Ioc
Tdd,IocTdd,Ioc
Tdd,Ioc
 
.Net template solution architecture
.Net template solution architecture.Net template solution architecture
.Net template solution architecture
 
Hibernate presentation
Hibernate presentationHibernate presentation
Hibernate presentation
 
Dependency injection in CakePHP
Dependency injection in CakePHPDependency injection in CakePHP
Dependency injection in CakePHP
 
Example Of Import Java
Example Of Import JavaExample Of Import Java
Example Of Import Java
 
The Spring Framework: A brief introduction to Inversion of Control
The Spring Framework:A brief introduction toInversion of ControlThe Spring Framework:A brief introduction toInversion of Control
The Spring Framework: A brief introduction to Inversion of Control
 
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
 
O365 Saturday - Deepdive SharePoint Client Side Rendering
O365 Saturday - Deepdive SharePoint Client Side RenderingO365 Saturday - Deepdive SharePoint Client Side Rendering
O365 Saturday - Deepdive SharePoint Client Side Rendering
 
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
 
...and thus your forms automagically disappeared
...and thus your forms automagically disappeared...and thus your forms automagically disappeared
...and thus your forms automagically disappeared
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong Foundations
 
CommercialSystemsBahman.ppt
CommercialSystemsBahman.pptCommercialSystemsBahman.ppt
CommercialSystemsBahman.ppt
 
Grails patterns and practices
Grails patterns and practicesGrails patterns and practices
Grails patterns and practices
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
 
ARabia hossain project report.pdf
ARabia hossain project report.pdfARabia hossain project report.pdf
ARabia hossain project report.pdf
 
Il 09 T3 William Spreitzer
Il 09 T3 William SpreitzerIl 09 T3 William Spreitzer
Il 09 T3 William Spreitzer
 
javascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.pptjavascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.ppt
 
Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Code
 

Recently uploaded

Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROmotivationalword821
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 

Recently uploaded (20)

Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTRO
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 

Functional programming in C#

  • 1. Functional Programming in C# NCrafts 21-22 May, Paris 2015 @tjaskula
  • 2. What is functional programming ? • Functions as building blocks • Function returns values only based on the passed input • Recursion • HOF (Higher Order Functions) • Creation of anonymous functions, in-line, lambda expressions • Closures • Immutability
  • 3. What REALY is FP ? “Natural way of telling the computer what it should do, by describing properties of a given problem in a concise language”
  • 4. Programmers responsibility in FP ? Specify functions to describe a given set of problems
  • 5. Object Oriented Programming • Encapsulation • Combining data and behavior into classes and objects • Modeling Real-World
  • 6. Relationship FP to OOP • No silver bullet • Programmer needs to understand different techniques
  • 7. Why to talk about ? • Concurrency programming models • Writing software it’s a complex process • Managing side effects
  • 8. Part 1 – Make it simple Composing dependencies
  • 9. The OOP way IoC container granted from the start. Developers argue about which framework to chose and not the problem to solve.
  • 10. 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 } }
  • 11. New requirements Log, Security, Audit, Cache…Cross Cutting Concerns
  • 12. 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);
  • 13. …or better… AOP to the rescue
  • 14. [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 } }
  • 15. Yes, but container can do more !
  • 16. AOP with interception var calculator = new Calculator(); var calculatorProxy = Intercept.ThroughProxy<ICalculator>(calculator, new InterfaceInterceptor(), new[] { new LogBehavior() });
  • 17. 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
  • 18. Really ?!!! Is this… SIMPLE ?
  • 19.
  • 20. 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();
  • 21. 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();
  • 22. 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>();
  • 23. 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>();
  • 24. 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">
  • 25. 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">
  • 26. 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">
  • 27. What problem do we try to solve ? • Decoupling ? • Testing ? • Modular Design ? • Dependencies management ?
  • 28. 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
  • 29. 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
  • 30. 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....
  • 31. 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…
  • 32. The rest is Plumbing code
  • 33. Functional way int Multiply(int a, int b) { return a * b; } Partial application Func<int, int> multiplyBy10 = b => Multiply(10, b);
  • 34. 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) { return (a + 7) * 10; } int CalcCFromA(int a) { return CalcC(CalcB(a)); } let calcCFromA = calcB >> calcC
  • 35. 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…
  • 36. 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…
  • 37. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); var pipeline = c => handlers.Enroll(studentRepository, classRepository, c); Bootstrap in one place…
  • 39. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); var pipeline = c => handlers.Log(c, c1 => handlers.Enroll(studentRepository, classRepository, c1)); Want to log ?
  • 40. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); var studentEnrollPipeline = c => handlers.Audit(c, c1 => handlers.Log(c1, c2 => handlers.Enroll(studentRepository,classRepository, c2)); Audit ?
  • 41. var lifeTime = new LifeTime(); var studentRepositoryFactory = () => new StudentRepository(); var classRepositoryFactory = () => new ClassRepository(); var studentEnrollPipeline = c => handlers.Audit(c, c1 => handlers.Log(c1, c2 => handlers.Enroll(lifeTime.PerThread(studentRepositoryFactory), lifeTime.PerThread(classRepositoryFactory), c2)); Lifetime management ?
  • 42. 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
  • 43. To many dependencies ? • You have another serious problem
  • 44. Is this… SIMPLE ? Is is just pure C# code
  • 45. Part 2 – Control complexity Composition strikes again…but in different shape
  • 46. Writing a program using functions How to order sequence of functions ? ParseCopyright(string text) { return text + “©” } ParseAppendix(string text) { return text.Remove(“APPENDIX”); }
  • 48. But this can fail ParseAppendix function may throw an exception
  • 49. Solution Return two kind of things from ParseAppendix function string string Instead of Let’s allow string string Error or
  • 50. But function can return one thing And only one thing
  • 51. Solution Put in in the box string ParseResult
  • 52. What happens to this now ? ParseCopyright(ParseAppendix(text)); string ParseResultParseAppendix ParseCopyright
  • 53. is success Solution Let’s have a special “link”/”connect”/”compose” function string ParseResultParseAppendix ParseCopyrightstring Error Connect
  • 54. What we have seen is a… M***D
  • 55. Demo
  • 56.
  • 57.
  • 58. Composition Composition is the key to controlling complexity in software. “In our study of program design, we have seen that expert programmers control the complexity of their designs with the same general techniques used by designers of all complex systems. They combine primitive elements to form compound objects, they abstract compound objects to form higher-level building blocks, and they preserve modularity by adopting appropriate large-scale views of system structure.”
  • 59. Should I do functional programming in C# ?
  • 60. To take away • Be stupid! Don’t waste your brain on complicated code • Don’t waste your time to understand Rube Goldberg machines • Simplicity. Write only the code that matters. • Readability • Less bugs

Editor's Notes

  1. Functional programmers use functions as building blocks to create new functions. There are other language elements available to them but the function is the main construct that the architecture is built from Referential transparency or pure functions. In OOP program state often influences the return of the function
  2. What the problem you’re solving and not describing the precise way of the solution
  3. Then computer can decide on best evaluation order Parallization opportunities If certain functions can be evaluated at all
  4. Programmer needs to understand different techniques and make decisions for and against them based on the problem to solve at hand
  5. Very hard to achieve with imperative program accessing shared state. Store data in one place for read and writes (needs LOCKS) when accessible by many functions Complex process can be controlled by composition Side effects cannot be removed completely but can be reduced significantly
  6. 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.
  7. 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 ?
  8. 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
  9. Can I explain it to junior developer ?
  10. How can we say what is to be executed first? How can we form an ordered sequence of functions
  11. How can we say what is to be executed first? How can we form an ordered sequence of functions
  12. And, we don't want to change every function we could connect with ParseAppendix to consume a ParseResult .
  13. That way, we can, behind the scenes, adapt the output of one function to feed the following one. This algorithm must be written only once per "boxing type" (different box, different adapting algorithm)
  14. A Monad is a pattern for doing function composition with ‘amplified’ types. You can think of an amplified type as a generic type with a single type parameter. IEnumerable<T> is a very good example. Monads provide techniques for removing repetitive and awkward code and can allow us to significantly simplify many programming problems.
  15. Composition is the key to controlling complexity in software.