SlideShare ist ein Scribd-Unternehmen logo
1 von 28
Downloaden Sie, um offline zu lesen
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Implementing Clean Architecture
Florin Coroș
onCodeDesign.com | www.infiniswiss.com | www.iquarc.com
florin@onCodeDesign.com
@florincoros
.com
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Many thanks to our sponsors & partners!
GOLD
SILVER
PARTNERS
PLATINUM
POWERED BY
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Co-Founder & Partner
About me
@florincoros
Partner
https://onCodeDesign.com/training
Co-Founder & Partner
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Implementing Clean Architecture
Florin Coroș
onCodeDesign.com | www.infiniswiss.com | www.iquarc.com
florin@onCodeDesign.com
@florincoros
.com
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Why is Architecture Important
-- Robert C. Martin, Clean Architecture
The goal of software architecture is to minimize
the human resources required to build and
maintain the required system
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Decompose - Separation of Concerns
Title
Title
Title
Title
Title
Title
Title
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Manage the Complexity and Size
when projects do fail for reasons that are
primarily technical, the reason is often
uncontrolled complexity
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
The Architecture is Separation of Concerns and a Set of Rules
External
Interfaces
UI Frameworks
Devices
Controllers
EntitiesEntities
Use Cases
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Implementing the Architecture
External
Interfaces
UI Frameworks
Devices
Controllers
EntitiesEntities
Use Cases
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Structure that Supports the Architecture
External
Interfaces
UI Frameworks
Devices
Controllers
EntitiesEntities
Use Cases
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Clean Architecture
External
Interfaces
UI Frameworks
Devices
Controllers
EntitiesEntities
Use Cases
http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
Presenter
Controller
UseCase
Implementation
Presenter
Controller
UseCase
Implementation
UseCase
InputAbstraction
UseCase
OutputAbstraction
Dependencies should be in one direction only
Source code dependencies can only point inwards
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Implementing Clean Architecture through Structure
‱ Hide external frameworks to enforce the way they are used
‱ Use assemblies and references among them to enforce rules
‱ Enforce Constructor Dependency Injection that encourages
Programming Against Interfaces
Create a structure that makes it difficult to write bad code and it makes it easy to write good
code, code that follows the architecture and the design
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Creating a Structure for Clean Architecture
<<interface>><<interface>>
ILogger
+LogError()
Logger
+LogError()
<<public interface>><<public interface>>
ILogger
+LogError()
<<Internal class>><<Internal class>>
Logger
+LogError()
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Hide External Libraries from App Code
<<Internal class>><<Internal class>>
Exception Wrappers
<<public
Interface>>
<<public
Interface>>
API Interfaces
<<Internal class>><<Internal class>>
Decorators
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
<<Interface>>
TDataModel
IRepository
+GetEntities<TDataModel>()
<<Interface>>
TDataModel
IUnitOfWork
+GetEntities<TDataModel>()
+SaveChanges()
Database
EfRepository EfUnitOfWork
<<Stereotype>>
<<DTO>>
Order
<<DTO>>
Person
Enforce Separation of Data Access Concerns
iQuarcDataAccess
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
DIP to Enforce Separation of Data Access Concern
<<Interface>>
IDbContextFactory
+CreateContext()
Database
<<DTO>>
Customer<<DTO>>
Order<<DTO>>
Person
UnitOfWork
Repository DbContextFactory
<<Interface>>
TDataModel
IRepository, IUnitOfWork
+GetEntities()
+SaveEntities()
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
AppBoot: DI Abstractions & Type Discovery
<<Interface>>
TDataModel
<<Interface>>
TDataModel
IEntityInterceptor
+OnLoad()
+OnSaving()
<<Interface>>
TDataModel
<<Interface>>
TDataModel
IDbContextFactory
+CreateContext()
Database
<<DTO>><<DTO>>
Customer<<DTO>><<DTO>>
Order<<DTO>><<DTO>>
Person
<<DTO>>
Customer<<DTO>>
Order<<DTO>>
Person
UnitOfWork
Repository
UnitOfWork
Repository DbContextFactory
<<Attribute>><<Attribute>>
ServiceAttribute
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
<<Attribute>>
ServiceAttribute
+ServiceAttribute(interface : Type )
Bootstrapper
+Run()
<<Internal>>
DependencyContainerAdapter
iQuarcAppBoot
AppBoot Hides the DI Framework under Abstractions
public interface IPriceCalculator
{
int CalculateTaxes(Order o, Customer c);
int CalculateDiscount(Order o, Customer c);
}
[Service(typeof(IPriceCalculator), Lifetime.Instance)]
interal class PriceCalculator : IPriceCalculator
{
public int CalculateTaxes(Order o, Customer c)
{
return 10; // do actual calculation
}
public int CalculateDiscount(Order o, Customer c)
{
return 20; // do actual calculation
}
}
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Patters for Creating Services that Depend Only on Interfaces
[Service(typeof (IOrderingService))]
private class OrderingService : IOrderingService
{
private readonly IRepository repository;
private readonly IPriceCalculator calculator;
private readonly IApprovalService orderApproval;
public OrderingService(IRepository repository, IPriceCalculator calculator, IApprovalService orderApproval)
{
this.repository = repository;
this.calculator = calculator;
this.orderApproval = orderApproval;
}
public SalesOrderInfo[] GetOrdersInfo(string customerName)
{
var orders = repository.GetEntities<SalesOrderHeader>()
...
return orders.ToArray();
}
public SalesOrderResult PlaceOrder(string customerName, OrderRequest request)
{
...
}
}
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Enforce Constructor DI to Prevent Circular Dependencies
[Service(typeof(IApprovalService))]
class ApprovalService : IApprovalService
{
private readonly IPriceCalculator priceCalculator;
public ApprovalService(IPriceCalculator priceCalculator)
{
this.priceCalculator = priceCalculator;
}
...
}
[Service(typeof (IPriceCalculator), Lifetime.Instance)]
public class PriceCalculator : IPriceCalculator
{
private readonly IApprovalService approvalService;
public PriceCalculator(IApprovalService approvalService)
{
this.approvalService = approvalService;
}
...
}
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
<<Interface>>
TDataModel
IRepository
+GetEntities<TDataModel>()
<<Interface>>
TDataModel
IUnitOfWork
+GetEntities<TDataModel>()
+SaveChanges()
Database
EfRepository EfUnitOfWork
<<Stereotype>>
<<DTO>>
Order
<<DTO>>
Person
Encapsulate Data Access Concerns
iQuarcDataAccess
[Service(typeof (IRepository))]
internal class EfRepository : IRepository, IDisposable
{
private readonly IDbContextFactory contextFactory;
private readonly IInterceptorsResolver interceptorsResolver;
private DbContext context;
private readonly IEnumerable<IEntityInterceptor> interceptors;
public EfRepository(IDbContextFactory contextFactory,
IInterceptorsResolver resolver)
{
this.contextFactory = contextFactory;
this.interceptorsResolver = interceptorsResolver;
this.interceptors =
resolver.GetGlobalInterceptors();
}
...
}
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
public interface IRepository
{
IQueryable<TDbEntity> GetEntities<TDbEntity>() where TDbEntity : class;
IUnitOfWork CreateUnitOfWork();
}
public interface IUnitOfWork : IRepository, IDisposable
{
void SaveChanges();
void Add<T>(T entity) where T : class;
void Delete<T>(T entity) where T : class;
void BeginTransactionScope(SimplifiedIsolationLevel isolation);
}
Create Separated Patterns for Read-Only and
Read-Write
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Patterns for Read-Only data
public class OrdersController : Controller
{
private readonly IRepository repository;
public OrdersController(IRepository repository)
{
this.repository = repository;
}
public IActionResult Index(string customer)
{
var orders = repository.GetEntities<SalesOrderHeader>()
.Where(soh => soh.Customer.Person.LastName == customer)
.Select(soh => new OrdersListViewModel
{
CustomerName = customer,
Number = soh.SalesOrderNumber,
SalesPersonName = soh.SalesPerson,
DueDate = soh.DueDate,
});
return View(orders);
}
...
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Patterns for Read-Write data
public class OrdersController : Controller
{
...
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult PlaceOrder(OrderRequestViewModel model)
{
...
using (IUnitOfWork uof = repository.CreateUnitOfWork())
{
SalesOrderHeader order = uof.GetEntities<SalesOrderHeader>()
.FirstOrDefault(o => o.CustomerID == c.ID && o.OrderDate.Month == DateTime.Now.Month);
if (order == null)
{
order = new SalesOrderHeader {Customer = c};
uof.Add(order);
}
AddRequestToOrder(model, order);
uof.SaveChanges();
}
...
}
}
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Consistency Creates Optimizations Opportunities
internal class EfRepository : IRepository, IDisposable
{
public IQueryable<T> GetEntities<T>() where T : class
{
return Context.Set<T>().AsNoTracking();
}
public IUnitOfWork CreateUnitOfWork()
{
return new EfUnitOfWork(contextFactory, interceptorsResolver);
}
private sealed class EfUnitOfWork : IUnitOfWork
{
private DbContext context;
private TransactionScope transactionScope;
private readonly IDbContextFactory contextFactory;
public EfUnitOfWork(IDbContextFactory contextFactory, IInterceptorsResolver resolver)
{
this.contextFactory = contextFactory;
this.interceptorsResolver = interceptorsResolver;
}
}
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Create Development Patterns in Code
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Implementing Clean Architecture through Structure
External
Interfaces
UI Frameworks
Devices
Controllers
EntitiesEntities
Use Cases
<<Attribute>><<Attribute>>
ServiceAttribute
RepositoryImpl
+ GetEntities<T>() : IQueriable()
+ SaveChanges()
Hide external frameworks to enforce the way they are used
Use assemblies and references among them to enforce rules
Enforce Constructor Dependency Injection that encourages Programming Against
Interfaces
/iQuarc
iQuarc
onCodeDesign.com/training
@ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Florin Coroș
Author & Trainer, onCodeDesign onCodeDesign.com
Co-founder & Partner, InfiniSwiss www.infiniswiss.com
Co-founder & Partner, iQuarc www.iquarc.com
email: florin@onCodeDesign.com
blog: onCodeDesign.com
tweet: @florincoros
https://onCodeDesign.com/training

Weitere Àhnliche Inhalte

Ähnlich wie ITCamp 2019 - Florin Coros - Implementing Clean Architecture

Ähnlich wie ITCamp 2019 - Florin Coros - Implementing Clean Architecture (20)

Xamarin Under The Hood - Dan Ardelean
 Xamarin Under The Hood - Dan Ardelean Xamarin Under The Hood - Dan Ardelean
Xamarin Under The Hood - Dan Ardelean
 
The Fine Art of Time Travelling - Implementing Event Sourcing - Andrea Saltar...
The Fine Art of Time Travelling - Implementing Event Sourcing - Andrea Saltar...The Fine Art of Time Travelling - Implementing Event Sourcing - Andrea Saltar...
The Fine Art of Time Travelling - Implementing Event Sourcing - Andrea Saltar...
 
ITCamp 2019 - Emil Craciun - RoboRestaurant of the future powered by serverle...
ITCamp 2019 - Emil Craciun - RoboRestaurant of the future powered by serverle...ITCamp 2019 - Emil Craciun - RoboRestaurant of the future powered by serverle...
ITCamp 2019 - Emil Craciun - RoboRestaurant of the future powered by serverle...
 
Everyone Loves Docker Containers Before They Understand Docker Containers - A...
Everyone Loves Docker Containers Before They Understand Docker Containers - A...Everyone Loves Docker Containers Before They Understand Docker Containers - A...
Everyone Loves Docker Containers Before They Understand Docker Containers - A...
 
The fight for surviving in the IoT world
The fight for surviving in the IoT worldThe fight for surviving in the IoT world
The fight for surviving in the IoT world
 
The fight for surviving in the IoT world - Radu Vunvulea
The fight for surviving in the IoT world - Radu VunvuleaThe fight for surviving in the IoT world - Radu Vunvulea
The fight for surviving in the IoT world - Radu Vunvulea
 
Enforce Consistentcy with Clean Architecture
Enforce Consistentcy with Clean ArchitectureEnforce Consistentcy with Clean Architecture
Enforce Consistentcy with Clean Architecture
 
How to secure and manage modern IT - Ondrej Vysek
 How to secure and manage modern IT - Ondrej Vysek How to secure and manage modern IT - Ondrej Vysek
How to secure and manage modern IT - Ondrej Vysek
 
Day zero of a cloud project Radu Vunvulea ITCamp 2018
Day zero of a cloud project Radu Vunvulea ITCamp 2018Day zero of a cloud project Radu Vunvulea ITCamp 2018
Day zero of a cloud project Radu Vunvulea ITCamp 2018
 
ITCamp 2019 - Andrea Saltarello - Modernise your app. The Cloud Story
ITCamp 2019 - Andrea Saltarello - Modernise your app. The Cloud StoryITCamp 2019 - Andrea Saltarello - Modernise your app. The Cloud Story
ITCamp 2019 - Andrea Saltarello - Modernise your app. The Cloud Story
 
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
 
Blockchain for mere mortals - understand the fundamentals and start building ...
Blockchain for mere mortals - understand the fundamentals and start building ...Blockchain for mere mortals - understand the fundamentals and start building ...
Blockchain for mere mortals - understand the fundamentals and start building ...
 
Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017
 
Azure SQL Database From A Developer's Perspective - Alex Mang
Azure SQL Database From A Developer's Perspective - Alex MangAzure SQL Database From A Developer's Perspective - Alex Mang
Azure SQL Database From A Developer's Perspective - Alex Mang
 
Azure Microservices in Practice, Radu Vunvulea, ITCamp 2016
Azure Microservices in Practice, Radu Vunvulea, ITCamp 2016Azure Microservices in Practice, Radu Vunvulea, ITCamp 2016
Azure Microservices in Practice, Radu Vunvulea, ITCamp 2016
 
Modern cybersecurity threats, and shiny new tools to help deal with them
Modern cybersecurity threats, and shiny new tools to help deal with themModern cybersecurity threats, and shiny new tools to help deal with them
Modern cybersecurity threats, and shiny new tools to help deal with them
 
Modern cybersecurity threats, and shiny new tools to help deal with them - T...
 Modern cybersecurity threats, and shiny new tools to help deal with them - T... Modern cybersecurity threats, and shiny new tools to help deal with them - T...
Modern cybersecurity threats, and shiny new tools to help deal with them - T...
 
Azure Microservices in Practice - Radu Vunvulea
Azure Microservices in Practice - Radu VunvuleaAzure Microservices in Practice - Radu Vunvulea
Azure Microservices in Practice - Radu Vunvulea
 
ITCamp 2018 - Ionut Balan - A beginner’s guide to Windows Mixed Reality
ITCamp 2018 - Ionut Balan - A beginner’s guide to Windows Mixed RealityITCamp 2018 - Ionut Balan - A beginner’s guide to Windows Mixed Reality
ITCamp 2018 - Ionut Balan - A beginner’s guide to Windows Mixed Reality
 
Creating Web and Mobile Apps with Angular 2 - George Saadeh
Creating Web and Mobile Apps with Angular 2 - George SaadehCreating Web and Mobile Apps with Angular 2 - George Saadeh
Creating Web and Mobile Apps with Angular 2 - George Saadeh
 

Mehr von ITCamp

ITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UX
ITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UXITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UX
ITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UX
ITCamp
 

Mehr von ITCamp (20)

ITCamp 2019 - Stacey M. Jenkins - Protecting your company's data - By psychol...
ITCamp 2019 - Stacey M. Jenkins - Protecting your company's data - By psychol...ITCamp 2019 - Stacey M. Jenkins - Protecting your company's data - By psychol...
ITCamp 2019 - Stacey M. Jenkins - Protecting your company's data - By psychol...
 
ITCamp 2019 - Silviu Niculita - Supercharge your AI efforts with the use of A...
ITCamp 2019 - Silviu Niculita - Supercharge your AI efforts with the use of A...ITCamp 2019 - Silviu Niculita - Supercharge your AI efforts with the use of A...
ITCamp 2019 - Silviu Niculita - Supercharge your AI efforts with the use of A...
 
ITCamp 2019 - Peter Leeson - Managing Skills
ITCamp 2019 - Peter Leeson - Managing SkillsITCamp 2019 - Peter Leeson - Managing Skills
ITCamp 2019 - Peter Leeson - Managing Skills
 
ITCamp 2019 - Mihai Tataran - Governing your Cloud Resources
ITCamp 2019 - Mihai Tataran - Governing your Cloud ResourcesITCamp 2019 - Mihai Tataran - Governing your Cloud Resources
ITCamp 2019 - Mihai Tataran - Governing your Cloud Resources
 
ITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UX
ITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UXITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UX
ITCamp 2019 - Ivana Milicic - Color - The Shadow Ruler of UX
 
ITCamp 2019 - Florin Loghiade - Azure Kubernetes in Production - Field notes...
ITCamp 2019 - Florin Loghiade -  Azure Kubernetes in Production - Field notes...ITCamp 2019 - Florin Loghiade -  Azure Kubernetes in Production - Field notes...
ITCamp 2019 - Florin Loghiade - Azure Kubernetes in Production - Field notes...
 
ITCamp 2019 - Florin Flestea - How 3rd Level support experience influenced m...
ITCamp 2019 - Florin Flestea -  How 3rd Level support experience influenced m...ITCamp 2019 - Florin Flestea -  How 3rd Level support experience influenced m...
ITCamp 2019 - Florin Flestea - How 3rd Level support experience influenced m...
 
ITCamp 2019 - Eldert Grootenboer - Cloud Architecture Recipes for The Enterprise
ITCamp 2019 - Eldert Grootenboer - Cloud Architecture Recipes for The EnterpriseITCamp 2019 - Eldert Grootenboer - Cloud Architecture Recipes for The Enterprise
ITCamp 2019 - Eldert Grootenboer - Cloud Architecture Recipes for The Enterprise
 
ITCamp 2019 - Cristiana Fernbach - Blockchain Legal Trends
ITCamp 2019 - Cristiana Fernbach - Blockchain Legal TrendsITCamp 2019 - Cristiana Fernbach - Blockchain Legal Trends
ITCamp 2019 - Cristiana Fernbach - Blockchain Legal Trends
 
ITCamp 2019 - Andy Cross - Machine Learning with ML.NET and Azure Data Lake
ITCamp 2019 - Andy Cross - Machine Learning with ML.NET and Azure Data LakeITCamp 2019 - Andy Cross - Machine Learning with ML.NET and Azure Data Lake
ITCamp 2019 - Andy Cross - Machine Learning with ML.NET and Azure Data Lake
 
ITCamp 2019 - Andy Cross - Business Outcomes from AI
ITCamp 2019 - Andy Cross - Business Outcomes from AIITCamp 2019 - Andy Cross - Business Outcomes from AI
ITCamp 2019 - Andy Cross - Business Outcomes from AI
 
ITCamp 2019 - Andrea Saltarello - Implementing bots and Alexa skills using Az...
ITCamp 2019 - Andrea Saltarello - Implementing bots and Alexa skills using Az...ITCamp 2019 - Andrea Saltarello - Implementing bots and Alexa skills using Az...
ITCamp 2019 - Andrea Saltarello - Implementing bots and Alexa skills using Az...
 
ITCamp 2019 - Alex Mang - I'm Confused Should I Orchestrate my Containers on ...
ITCamp 2019 - Alex Mang - I'm Confused Should I Orchestrate my Containers on ...ITCamp 2019 - Alex Mang - I'm Confused Should I Orchestrate my Containers on ...
ITCamp 2019 - Alex Mang - I'm Confused Should I Orchestrate my Containers on ...
 
ITCamp 2019 - Alex Mang - How Far Can Serverless Actually Go Now
ITCamp 2019 - Alex Mang - How Far Can Serverless Actually Go NowITCamp 2019 - Alex Mang - How Far Can Serverless Actually Go Now
ITCamp 2019 - Alex Mang - How Far Can Serverless Actually Go Now
 
ITCamp 2019 - Peter Leeson - Vitruvian Quality
ITCamp 2019 - Peter Leeson - Vitruvian QualityITCamp 2019 - Peter Leeson - Vitruvian Quality
ITCamp 2019 - Peter Leeson - Vitruvian Quality
 
ITCamp 2018 - Ciprian Sorlea - Million Dollars Hello World Application
ITCamp 2018 - Ciprian Sorlea - Million Dollars Hello World ApplicationITCamp 2018 - Ciprian Sorlea - Million Dollars Hello World Application
ITCamp 2018 - Ciprian Sorlea - Million Dollars Hello World Application
 
ITCamp 2018 - Ciprian Sorlea - Enterprise Architectures with TypeScript And F...
ITCamp 2018 - Ciprian Sorlea - Enterprise Architectures with TypeScript And F...ITCamp 2018 - Ciprian Sorlea - Enterprise Architectures with TypeScript And F...
ITCamp 2018 - Ciprian Sorlea - Enterprise Architectures with TypeScript And F...
 
ITCamp 2018 - Mete Atamel Ian Talarico - Google Home meets .NET containers on...
ITCamp 2018 - Mete Atamel Ian Talarico - Google Home meets .NET containers on...ITCamp 2018 - Mete Atamel Ian Talarico - Google Home meets .NET containers on...
ITCamp 2018 - Mete Atamel Ian Talarico - Google Home meets .NET containers on...
 
ITCamp 2018 - Magnus MĂ„rtensson - Azure Global Application Perspectives
ITCamp 2018 - Magnus MĂ„rtensson - Azure Global Application PerspectivesITCamp 2018 - Magnus MĂ„rtensson - Azure Global Application Perspectives
ITCamp 2018 - Magnus MĂ„rtensson - Azure Global Application Perspectives
 
ITCamp 2018 - Magnus MĂ„rtensson - Azure Resource Manager For The Win
ITCamp 2018 - Magnus MĂ„rtensson - Azure Resource Manager For The WinITCamp 2018 - Magnus MĂ„rtensson - Azure Resource Manager For The Win
ITCamp 2018 - Magnus MĂ„rtensson - Azure Resource Manager For The Win
 

KĂŒrzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

KĂŒrzlich hochgeladen (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 

ITCamp 2019 - Florin Coros - Implementing Clean Architecture

  • 1. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Implementing Clean Architecture Florin Coroș onCodeDesign.com | www.infiniswiss.com | www.iquarc.com florin@onCodeDesign.com @florincoros .com
  • 2. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Many thanks to our sponsors & partners! GOLD SILVER PARTNERS PLATINUM POWERED BY
  • 3. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Co-Founder & Partner About me @florincoros Partner https://onCodeDesign.com/training Co-Founder & Partner
  • 4. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Implementing Clean Architecture Florin Coroș onCodeDesign.com | www.infiniswiss.com | www.iquarc.com florin@onCodeDesign.com @florincoros .com
  • 5. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Why is Architecture Important -- Robert C. Martin, Clean Architecture The goal of software architecture is to minimize the human resources required to build and maintain the required system
  • 6. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Decompose - Separation of Concerns Title Title Title Title Title Title Title
  • 7. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Manage the Complexity and Size when projects do fail for reasons that are primarily technical, the reason is often uncontrolled complexity
  • 8. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals The Architecture is Separation of Concerns and a Set of Rules External Interfaces UI Frameworks Devices Controllers EntitiesEntities Use Cases
  • 9. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Implementing the Architecture External Interfaces UI Frameworks Devices Controllers EntitiesEntities Use Cases
  • 10. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Structure that Supports the Architecture External Interfaces UI Frameworks Devices Controllers EntitiesEntities Use Cases
  • 11. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Clean Architecture External Interfaces UI Frameworks Devices Controllers EntitiesEntities Use Cases http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html Presenter Controller UseCase Implementation Presenter Controller UseCase Implementation UseCase InputAbstraction UseCase OutputAbstraction Dependencies should be in one direction only Source code dependencies can only point inwards
  • 12. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Implementing Clean Architecture through Structure ‱ Hide external frameworks to enforce the way they are used ‱ Use assemblies and references among them to enforce rules ‱ Enforce Constructor Dependency Injection that encourages Programming Against Interfaces Create a structure that makes it difficult to write bad code and it makes it easy to write good code, code that follows the architecture and the design
  • 13. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Creating a Structure for Clean Architecture <<interface>><<interface>> ILogger +LogError() Logger +LogError() <<public interface>><<public interface>> ILogger +LogError() <<Internal class>><<Internal class>> Logger +LogError()
  • 14. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Hide External Libraries from App Code <<Internal class>><<Internal class>> Exception Wrappers <<public Interface>> <<public Interface>> API Interfaces <<Internal class>><<Internal class>> Decorators
  • 15. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals <<Interface>> TDataModel IRepository +GetEntities<TDataModel>() <<Interface>> TDataModel IUnitOfWork +GetEntities<TDataModel>() +SaveChanges() Database EfRepository EfUnitOfWork <<Stereotype>> <<DTO>> Order <<DTO>> Person Enforce Separation of Data Access Concerns iQuarcDataAccess
  • 16. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals DIP to Enforce Separation of Data Access Concern <<Interface>> IDbContextFactory +CreateContext() Database <<DTO>> Customer<<DTO>> Order<<DTO>> Person UnitOfWork Repository DbContextFactory <<Interface>> TDataModel IRepository, IUnitOfWork +GetEntities() +SaveEntities()
  • 17. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals AppBoot: DI Abstractions & Type Discovery <<Interface>> TDataModel <<Interface>> TDataModel IEntityInterceptor +OnLoad() +OnSaving() <<Interface>> TDataModel <<Interface>> TDataModel IDbContextFactory +CreateContext() Database <<DTO>><<DTO>> Customer<<DTO>><<DTO>> Order<<DTO>><<DTO>> Person <<DTO>> Customer<<DTO>> Order<<DTO>> Person UnitOfWork Repository UnitOfWork Repository DbContextFactory <<Attribute>><<Attribute>> ServiceAttribute
  • 18. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals <<Attribute>> ServiceAttribute +ServiceAttribute(interface : Type ) Bootstrapper +Run() <<Internal>> DependencyContainerAdapter iQuarcAppBoot AppBoot Hides the DI Framework under Abstractions public interface IPriceCalculator { int CalculateTaxes(Order o, Customer c); int CalculateDiscount(Order o, Customer c); } [Service(typeof(IPriceCalculator), Lifetime.Instance)] interal class PriceCalculator : IPriceCalculator { public int CalculateTaxes(Order o, Customer c) { return 10; // do actual calculation } public int CalculateDiscount(Order o, Customer c) { return 20; // do actual calculation } }
  • 19. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Patters for Creating Services that Depend Only on Interfaces [Service(typeof (IOrderingService))] private class OrderingService : IOrderingService { private readonly IRepository repository; private readonly IPriceCalculator calculator; private readonly IApprovalService orderApproval; public OrderingService(IRepository repository, IPriceCalculator calculator, IApprovalService orderApproval) { this.repository = repository; this.calculator = calculator; this.orderApproval = orderApproval; } public SalesOrderInfo[] GetOrdersInfo(string customerName) { var orders = repository.GetEntities<SalesOrderHeader>() ... return orders.ToArray(); } public SalesOrderResult PlaceOrder(string customerName, OrderRequest request) { ... } }
  • 20. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Enforce Constructor DI to Prevent Circular Dependencies [Service(typeof(IApprovalService))] class ApprovalService : IApprovalService { private readonly IPriceCalculator priceCalculator; public ApprovalService(IPriceCalculator priceCalculator) { this.priceCalculator = priceCalculator; } ... } [Service(typeof (IPriceCalculator), Lifetime.Instance)] public class PriceCalculator : IPriceCalculator { private readonly IApprovalService approvalService; public PriceCalculator(IApprovalService approvalService) { this.approvalService = approvalService; } ... }
  • 21. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals <<Interface>> TDataModel IRepository +GetEntities<TDataModel>() <<Interface>> TDataModel IUnitOfWork +GetEntities<TDataModel>() +SaveChanges() Database EfRepository EfUnitOfWork <<Stereotype>> <<DTO>> Order <<DTO>> Person Encapsulate Data Access Concerns iQuarcDataAccess [Service(typeof (IRepository))] internal class EfRepository : IRepository, IDisposable { private readonly IDbContextFactory contextFactory; private readonly IInterceptorsResolver interceptorsResolver; private DbContext context; private readonly IEnumerable<IEntityInterceptor> interceptors; public EfRepository(IDbContextFactory contextFactory, IInterceptorsResolver resolver) { this.contextFactory = contextFactory; this.interceptorsResolver = interceptorsResolver; this.interceptors = resolver.GetGlobalInterceptors(); } ... }
  • 22. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals public interface IRepository { IQueryable<TDbEntity> GetEntities<TDbEntity>() where TDbEntity : class; IUnitOfWork CreateUnitOfWork(); } public interface IUnitOfWork : IRepository, IDisposable { void SaveChanges(); void Add<T>(T entity) where T : class; void Delete<T>(T entity) where T : class; void BeginTransactionScope(SimplifiedIsolationLevel isolation); } Create Separated Patterns for Read-Only and Read-Write
  • 23. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Patterns for Read-Only data public class OrdersController : Controller { private readonly IRepository repository; public OrdersController(IRepository repository) { this.repository = repository; } public IActionResult Index(string customer) { var orders = repository.GetEntities<SalesOrderHeader>() .Where(soh => soh.Customer.Person.LastName == customer) .Select(soh => new OrdersListViewModel { CustomerName = customer, Number = soh.SalesOrderNumber, SalesPersonName = soh.SalesPerson, DueDate = soh.DueDate, }); return View(orders); } ...
  • 24. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Patterns for Read-Write data public class OrdersController : Controller { ... [HttpPost] [ValidateAntiForgeryToken] public IActionResult PlaceOrder(OrderRequestViewModel model) { ... using (IUnitOfWork uof = repository.CreateUnitOfWork()) { SalesOrderHeader order = uof.GetEntities<SalesOrderHeader>() .FirstOrDefault(o => o.CustomerID == c.ID && o.OrderDate.Month == DateTime.Now.Month); if (order == null) { order = new SalesOrderHeader {Customer = c}; uof.Add(order); } AddRequestToOrder(model, order); uof.SaveChanges(); } ... } }
  • 25. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Consistency Creates Optimizations Opportunities internal class EfRepository : IRepository, IDisposable { public IQueryable<T> GetEntities<T>() where T : class { return Context.Set<T>().AsNoTracking(); } public IUnitOfWork CreateUnitOfWork() { return new EfUnitOfWork(contextFactory, interceptorsResolver); } private sealed class EfUnitOfWork : IUnitOfWork { private DbContext context; private TransactionScope transactionScope; private readonly IDbContextFactory contextFactory; public EfUnitOfWork(IDbContextFactory contextFactory, IInterceptorsResolver resolver) { this.contextFactory = contextFactory; this.interceptorsResolver = interceptorsResolver; } }
  • 26. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Create Development Patterns in Code
  • 27. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Implementing Clean Architecture through Structure External Interfaces UI Frameworks Devices Controllers EntitiesEntities Use Cases <<Attribute>><<Attribute>> ServiceAttribute RepositoryImpl + GetEntities<T>() : IQueriable() + SaveChanges() Hide external frameworks to enforce the way they are used Use assemblies and references among them to enforce rules Enforce Constructor Dependency Injection that encourages Programming Against Interfaces /iQuarc iQuarc onCodeDesign.com/training
  • 28. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals Florin Coroș Author & Trainer, onCodeDesign onCodeDesign.com Co-founder & Partner, InfiniSwiss www.infiniswiss.com Co-founder & Partner, iQuarc www.iquarc.com email: florin@onCodeDesign.com blog: onCodeDesign.com tweet: @florincoros https://onCodeDesign.com/training