SlideShare a Scribd company logo
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Enforce Consistency through
Application Infrastructure
Florin Coros
www.rabs.ro | www.iquarc.com | onCodeDesign.com
florin.coros@rabs.ro
@florincoros
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Many thanks to our sponsors & partners!
GOLD
SILVER
PARTNERS
PLATINUM
POWERED BY
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals
About me
@florincoros
Founder & Partner
Partner
Partner
.com
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Many thanks to our sponsors & partners!
GOLD
SILVER
PARTNERS
PLATINUM
POWERED BY
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 5
Why Consistency is Key?
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 6
Impeded by Others Code?
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 7
Different Solutions to the Same Problem
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 8
Which one is the ONE?
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 9
Cost of Change
Wrong approach consistently
repeated in all of the
application screens
vs
Uniquely new approach in all
of the application screens
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 10
Managing Complexity
when projects do fail for reasons that are primarily
technical, the reason is often
uncontrolled complexity
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 11
Controlling the Complexity
uniqueness consistency
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 12
Rules Are Easy to Ignore
Quick and Dirty
vs
The only way to go fast, is to go well!
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 13
Quality through Discipline
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 14
Seniors May Be Overwhelmed with Review
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 15
Quality through Structure
• You enforce consistency with structure
• Create a structure that makes difficult to write
bad code rather then code that follows the
design
• You use assemblies and references among
them to enforce rules
• Hide external frameworks to enforce the way
they are used
• Enforce Constructor Dependency Injection and
encourage Programming Against Interfaces
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 16
Assure Consistency in Using External Library by Hiding It
<<static class>>
Log
+LogError()
+LogWarining()
Exception Wrappers Decorators
<<Interface>>
API Interfaces
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 17
public interface ILog
{
void Info(string message, params object[] args);
void Warn(string message, params object[] args);
void Error(string message, Exception ex);
}
Enforces Separation of Concerns
• The application code only knows about ILog
• Once I is defined we can develop screens and call this
interface to log traces or errors
– The real implementation can be done later
• If logging needs changes, we can modify the interfaces
at once in all places it is used
– The implementation is in only one place, so one place to
change only
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 18
Encapsulate Data Access Concerns
<<Interface>>
TDataModel
IRepository
+GetEntities<TDataModel>()
<<Interface>>
TDataModel
IUnitOfWork
+GetEntities<TDataModel>()
+SaveChanges()
Database
Repository UnitOfWork
<<Stereotype>>
<<DTO>>
Order
<<DTO>>
Person
[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();
}
...
} iQuarcDataAccess
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 19
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 #ITCAMP16Community Conference for IT Professionals 20
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 #ITCAMP16Community Conference for IT Professionals 21
Enforce Construction of Unit of Work
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 #ITCAMP16Community Conference for IT Professionals 22
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 #ITCAMP16Community Conference for IT Professionals 23
Create Development Patters in how Data is Accessed
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 24
Enforce Separation of Data Access Concerns
<<Interface>>
TDataModel
IRepository
+GetEntities<TDataModel>()
<<Interface>>
TDataModel
IUnitOfWork
+GetEntities<TDataModel>()
+SaveChanges()
Database
Repository UnitOfWork
<<Stereotype>>
<<DTO>>
Order<<DTO>>
Person
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 25
DIP to Enforce Separation of Data Access Concern
<<Interface>>
TDataModel
IEntityInterceptor
+OnLoad()
+OnSaving()
<<Interface>>
TDataModel
IDbContextFactory
+CreateContext()
Database
<<DTO>>
Customer<<DTO>>
Order <<DTO>>
Person
DbContextFactoryUnitOfWork
Repository
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 26
DIP to Enforce OnSave/OnLoad Logic out of Data Access
<<Interface>>
TDataModel
IEntityInterceptor
+OnLoad()
+OnSaving()
<<Interface>>
TDataModel
IDbContextFactory
+CreateContext()
DbContextFactoryUnitOfWork
Repository
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 27
AppBoot as Support
<<Attribute>>
ServiceAttribute
IModule
<<Interface>>
TDataModel
IEntityInterceptor
+OnLoad()
+OnSaving()
<<Interface>>
TDataModel
IRepository
Database
<<DTO>>
Customer<<DTO>>
Order<<DTO>>
Person
DbContextFactoryUnitOfWork
Repository
<<Interface>>
TDataModel
IUnitOfWork
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 28
AppBoot to Enforce Constructor Dependency Injection
<<Attribute>>
ServiceAttribute
+ ServiceAttribute()
+ServiceAttribute(Type contract)
+ ServiceAttribute(Type t, Lifetime lifetime)
Bootstrapper
+Bootstrapper(Assembly[] assemblies)
+Run()
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
}
}
iQuarcAppBoot
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 29
Software systems should separate the startup process, when the application objects are constructed and the
dependencies are “wired” together, from the runtime logic that takes over after startup
<<Interface>>
IModule
+ Initialize()
Application
+ Initialize()
*
+ Modules[]
AppModule1
+ Initialize()
AppModule2
+ Initialize()
Enforce Separation of Construction from Use
public static void Main(string[] args)
{
var assemblies = GetApplicationAssemblies().ToArray();
Bootstrapper bootstrapper = new Bootstrapper(assemblies);
bootstrapper.ConfigureWithUnity();
bootstrapper.AddRegistrationBehavior(new ServiceRegistrationBehavior());
bootstrapper.Run();
}
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 30
Patters for Creating Services that Depend Only on Interfaces
[Service(typeof (IOrderingService))]
public 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 #ITCAMP16Community Conference for IT Professionals 31
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 #ITCAMP16Community Conference for IT Professionals 32
Design Patterns like Composition or Chain of Responsibility
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 33
Development Patters in How Dependencies are Created
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 34
No References Between Modules -> Enforce Constraints
<<Attribute>>
ServiceAttribute
+ ServiceAttribute()
+ServiceAttribute(Type contract)
+ ServiceAttribute(Type t, Lifetime lifetime)
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 35
iQuarc iQuarc
Dependencies
Management
Design Patterns in
Service Composition
Enforce Consistency
through Structure
Enforce
Separation of Concerns
Patterns for
Queries & Commands
Interceptors for
Queries & Commands
Enforce Consistency through Application Infrastructure
iQuarcCode-Design-Training
@ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Florin Coros
Co-founder & Partner, iQuarc www.iquarc.com
Partner, Infiniswiss www.infiniswiss.com
.com
email: florin.coros@iquarc.com
blog: onCodeDesign.com
tweet: @florincoros

More Related Content

PDF
Cloud Ready Design through Application Software Infrastructure
PDF
Post-marxismo, postmarxismo, post marxismo
PDF
TRS 2015
PDF
Neo repubblicanismo, neorepubblicanismo, neo repubblicanismo
PPTX
Seo presentation for dfc stall in digital innovation fair 2107
PDF
OPTIMIZATION OF SOME MINERAL CONTENTS OF DRIED OSMO-PRETREATED GREEN BELL PEP...
PDF
Trampas ptf
PPTX
Miguel pato 28 oct2013
Cloud Ready Design through Application Software Infrastructure
Post-marxismo, postmarxismo, post marxismo
TRS 2015
Neo repubblicanismo, neorepubblicanismo, neo repubblicanismo
Seo presentation for dfc stall in digital innovation fair 2107
OPTIMIZATION OF SOME MINERAL CONTENTS OF DRIED OSMO-PRETREATED GREEN BELL PEP...
Trampas ptf
Miguel pato 28 oct2013

Viewers also liked (9)

PDF
Posicionamiento Estratégico - Cralos Folle - PAE 2014
PDF
PMA Guillermo Sicardi 2014 24 material gestion_competencias_resumen
PPTX
Presentacion sintético.monday.junio 2013
PDF
Attending-to-the-Silence-Attending to the Silence_ The Birth and life of a Po...
PDF
Ptf exponegocios 19 set participantes
PDF
Pablo faga
PPT
PPP - Eduardo Spósito
PDF
MDT-World-Press-Newsletter-Vol5No3
PPTX
Pgi miguel pato dia 02
Posicionamiento Estratégico - Cralos Folle - PAE 2014
PMA Guillermo Sicardi 2014 24 material gestion_competencias_resumen
Presentacion sintético.monday.junio 2013
Attending-to-the-Silence-Attending to the Silence_ The Birth and life of a Po...
Ptf exponegocios 19 set participantes
Pablo faga
PPP - Eduardo Spósito
MDT-World-Press-Newsletter-Vol5No3
Pgi miguel pato dia 02
Ad

Similar to Enforce Consistency through Application Infrastructure (20)

PPTX
Enforce Consistency through Application Infrastructure
PDF
Implementing Clean Architecture
PDF
ITCamp 2019 - Florin Coros - Implementing Clean Architecture
PDF
Enforce Consistency through Application Infrastructure
PDF
Enforce Consistentcy with Clean Architecture
PPTX
‘Cloud Ready’ Design through Application Software Infrastructure
PDF
ITCamp 2018 - Florin Coros - ‘Cloud Ready’ Design through Application Softwar...
DOC
10265 developing data access solutions with microsoft visual studio 2010
PDF
Udi Dahan Intentions And Interfaces
PDF
14147503 Intentions Interfaces Making Patterns Concrete
PDF
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
PPTX
Real World API Design Using The Entity Framework Services
PPTX
Seminar - Scalable Enterprise Application Development Using DDD and CQRS
PPTX
Lets focus on business value
PPTX
Lets focus on business value
PDF
seminar100326a.pdf
PDF
.Net template solution architecture
PDF
Aggregates, Entities and Value objects - Devnology 2010 community day
PPT
Domain Driven Design Demonstrated
PPTX
Introducing Entity Framework Core
Enforce Consistency through Application Infrastructure
Implementing Clean Architecture
ITCamp 2019 - Florin Coros - Implementing Clean Architecture
Enforce Consistency through Application Infrastructure
Enforce Consistentcy with Clean Architecture
‘Cloud Ready’ Design through Application Software Infrastructure
ITCamp 2018 - Florin Coros - ‘Cloud Ready’ Design through Application Softwar...
10265 developing data access solutions with microsoft visual studio 2010
Udi Dahan Intentions And Interfaces
14147503 Intentions Interfaces Making Patterns Concrete
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
Real World API Design Using The Entity Framework Services
Seminar - Scalable Enterprise Application Development Using DDD and CQRS
Lets focus on business value
Lets focus on business value
seminar100326a.pdf
.Net template solution architecture
Aggregates, Entities and Value objects - Devnology 2010 community day
Domain Driven Design Demonstrated
Introducing Entity Framework Core
Ad

Recently uploaded (20)

PPTX
fundraisepro pitch deck elegant and modern
DOCX
"Project Management: Ultimate Guide to Tools, Techniques, and Strategies (2025)"
PPTX
nose tajweed for the arabic alphabets for the responsive
PPTX
The spiral of silence is a theory in communication and political science that...
PPTX
water for all cao bang - a charity project
PPTX
Anesthesia and it's stage with mnemonic and images
PPTX
Self management and self evaluation presentation
PPTX
The Effect of Human Resource Management Practice on Organizational Performanc...
PDF
Parts of Speech Prepositions Presentation in Colorful Cute Style_20250724_230...
PPTX
S. Anis Al Habsyi & Nada Shobah - Klasifikasi Hambatan Depresi.pptx
PPTX
English-9-Q1-3-.pptxjkshbxnnxgchchxgxhxhx
PPTX
BIOLOGY TISSUE PPT CLASS 9 PROJECT PUBLIC
PDF
Swiggy’s Playbook: UX, Logistics & Monetization
PPTX
Emphasizing It's Not The End 08 06 2025.pptx
PPTX
Effective_Handling_Information_Presentation.pptx
PPT
First Aid Training Presentation Slides.ppt
PPTX
Primary and secondary sources, and history
PDF
natwest.pdf company description and business model
PPTX
Tablets And Capsule Preformulation Of Paracetamol
DOCX
ENGLISH PROJECT FOR BINOD BIHARI MAHTO KOYLANCHAL UNIVERSITY
fundraisepro pitch deck elegant and modern
"Project Management: Ultimate Guide to Tools, Techniques, and Strategies (2025)"
nose tajweed for the arabic alphabets for the responsive
The spiral of silence is a theory in communication and political science that...
water for all cao bang - a charity project
Anesthesia and it's stage with mnemonic and images
Self management and self evaluation presentation
The Effect of Human Resource Management Practice on Organizational Performanc...
Parts of Speech Prepositions Presentation in Colorful Cute Style_20250724_230...
S. Anis Al Habsyi & Nada Shobah - Klasifikasi Hambatan Depresi.pptx
English-9-Q1-3-.pptxjkshbxnnxgchchxgxhxhx
BIOLOGY TISSUE PPT CLASS 9 PROJECT PUBLIC
Swiggy’s Playbook: UX, Logistics & Monetization
Emphasizing It's Not The End 08 06 2025.pptx
Effective_Handling_Information_Presentation.pptx
First Aid Training Presentation Slides.ppt
Primary and secondary sources, and history
natwest.pdf company description and business model
Tablets And Capsule Preformulation Of Paracetamol
ENGLISH PROJECT FOR BINOD BIHARI MAHTO KOYLANCHAL UNIVERSITY

Enforce Consistency through Application Infrastructure

  • 1. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals Enforce Consistency through Application Infrastructure Florin Coros www.rabs.ro | www.iquarc.com | onCodeDesign.com florin.coros@rabs.ro @florincoros
  • 2. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals Many thanks to our sponsors & partners! GOLD SILVER PARTNERS PLATINUM POWERED BY
  • 3. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals About me @florincoros Founder & Partner Partner Partner .com
  • 4. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals Many thanks to our sponsors & partners! GOLD SILVER PARTNERS PLATINUM POWERED BY
  • 5. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 5 Why Consistency is Key?
  • 6. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 6 Impeded by Others Code?
  • 7. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 7 Different Solutions to the Same Problem
  • 8. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 8 Which one is the ONE?
  • 9. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 9 Cost of Change Wrong approach consistently repeated in all of the application screens vs Uniquely new approach in all of the application screens
  • 10. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 10 Managing Complexity when projects do fail for reasons that are primarily technical, the reason is often uncontrolled complexity
  • 11. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 11 Controlling the Complexity uniqueness consistency
  • 12. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 12 Rules Are Easy to Ignore Quick and Dirty vs The only way to go fast, is to go well!
  • 13. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 13 Quality through Discipline
  • 14. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 14 Seniors May Be Overwhelmed with Review
  • 15. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 15 Quality through Structure • You enforce consistency with structure • Create a structure that makes difficult to write bad code rather then code that follows the design • You use assemblies and references among them to enforce rules • Hide external frameworks to enforce the way they are used • Enforce Constructor Dependency Injection and encourage Programming Against Interfaces
  • 16. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 16 Assure Consistency in Using External Library by Hiding It <<static class>> Log +LogError() +LogWarining() Exception Wrappers Decorators <<Interface>> API Interfaces
  • 17. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 17 public interface ILog { void Info(string message, params object[] args); void Warn(string message, params object[] args); void Error(string message, Exception ex); } Enforces Separation of Concerns • The application code only knows about ILog • Once I is defined we can develop screens and call this interface to log traces or errors – The real implementation can be done later • If logging needs changes, we can modify the interfaces at once in all places it is used – The implementation is in only one place, so one place to change only
  • 18. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 18 Encapsulate Data Access Concerns <<Interface>> TDataModel IRepository +GetEntities<TDataModel>() <<Interface>> TDataModel IUnitOfWork +GetEntities<TDataModel>() +SaveChanges() Database Repository UnitOfWork <<Stereotype>> <<DTO>> Order <<DTO>> Person [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(); } ... } iQuarcDataAccess
  • 19. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 19 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
  • 20. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 20 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); } ... }
  • 21. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 21 Enforce Construction of Unit of Work 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; } }
  • 22. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 22 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(); } ... } }
  • 23. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 23 Create Development Patters in how Data is Accessed
  • 24. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 24 Enforce Separation of Data Access Concerns <<Interface>> TDataModel IRepository +GetEntities<TDataModel>() <<Interface>> TDataModel IUnitOfWork +GetEntities<TDataModel>() +SaveChanges() Database Repository UnitOfWork <<Stereotype>> <<DTO>> Order<<DTO>> Person
  • 25. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 25 DIP to Enforce Separation of Data Access Concern <<Interface>> TDataModel IEntityInterceptor +OnLoad() +OnSaving() <<Interface>> TDataModel IDbContextFactory +CreateContext() Database <<DTO>> Customer<<DTO>> Order <<DTO>> Person DbContextFactoryUnitOfWork Repository
  • 26. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 26 DIP to Enforce OnSave/OnLoad Logic out of Data Access <<Interface>> TDataModel IEntityInterceptor +OnLoad() +OnSaving() <<Interface>> TDataModel IDbContextFactory +CreateContext() DbContextFactoryUnitOfWork Repository
  • 27. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 27 AppBoot as Support <<Attribute>> ServiceAttribute IModule <<Interface>> TDataModel IEntityInterceptor +OnLoad() +OnSaving() <<Interface>> TDataModel IRepository Database <<DTO>> Customer<<DTO>> Order<<DTO>> Person DbContextFactoryUnitOfWork Repository <<Interface>> TDataModel IUnitOfWork
  • 28. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 28 AppBoot to Enforce Constructor Dependency Injection <<Attribute>> ServiceAttribute + ServiceAttribute() +ServiceAttribute(Type contract) + ServiceAttribute(Type t, Lifetime lifetime) Bootstrapper +Bootstrapper(Assembly[] assemblies) +Run() 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 } } iQuarcAppBoot
  • 29. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 29 Software systems should separate the startup process, when the application objects are constructed and the dependencies are “wired” together, from the runtime logic that takes over after startup <<Interface>> IModule + Initialize() Application + Initialize() * + Modules[] AppModule1 + Initialize() AppModule2 + Initialize() Enforce Separation of Construction from Use public static void Main(string[] args) { var assemblies = GetApplicationAssemblies().ToArray(); Bootstrapper bootstrapper = new Bootstrapper(assemblies); bootstrapper.ConfigureWithUnity(); bootstrapper.AddRegistrationBehavior(new ServiceRegistrationBehavior()); bootstrapper.Run(); }
  • 30. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 30 Patters for Creating Services that Depend Only on Interfaces [Service(typeof (IOrderingService))] public 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) { ... } }
  • 31. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 31 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; } ... }
  • 32. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 32 Design Patterns like Composition or Chain of Responsibility
  • 33. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 33 Development Patters in How Dependencies are Created
  • 34. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 34 No References Between Modules -> Enforce Constraints <<Attribute>> ServiceAttribute + ServiceAttribute() +ServiceAttribute(Type contract) + ServiceAttribute(Type t, Lifetime lifetime)
  • 35. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals 35 iQuarc iQuarc Dependencies Management Design Patterns in Service Composition Enforce Consistency through Structure Enforce Separation of Concerns Patterns for Queries & Commands Interceptors for Queries & Commands Enforce Consistency through Application Infrastructure iQuarcCode-Design-Training
  • 36. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals Florin Coros Co-founder & Partner, iQuarc www.iquarc.com Partner, Infiniswiss www.infiniswiss.com .com email: florin.coros@iquarc.com blog: onCodeDesign.com tweet: @florincoros

Editor's Notes

  • #4: My name is Florin Coros I live in Cluj-Napoca And I am under 35 I like to go to ROCK concerts I like to travel with my girl-friend I like to play GO. GO is a game that thought me to look a few steps ahead, which turned to be very useful for me… I tweet quite a lot I am a big fan of Uncle Bob I am a Software Architect at ISDC I am one of the cofounders of RABS I am part of iQuarc
  • #6: 4’ How many of you work in projects with more people? How many of you work alone?
  • #8: One solution to a common problem Consistent way to do: Data Access Dependency Injection … Logging Error Handling Localization Authorization Drawbacks: High Cost of Change Poor SoC Time to add new features is bigger -> less efficient Error prone
  • #9: Say the story ab DCV  increase complexity  increase accidental complexity When you see that in some places we use EF, in others ADO, in others stored procedures, you don’t know why and which one is the good one
  • #10: If consistency you can have one strategy, one solution with which you can fix or replace all at onece! - Its like being able to use an ReplaceALL function!
  • #12: 12’ We want our code to look like the one on the right! We want to be able to identify patterns on how our code is written I don’t necessary mean the known Design Patterns, but patterns specific to our project, Patterns that clearly say how we do things in this project, how this concern is addressed or implemented A system with patterns is going to have a manageable complexity. It is maintainable even if it is very complex and large is size Patterns make it simple A system in which everything is unique is going to be difficult to change and maintain. Even if it is small and simple, the uniqness, the chaos makes it complex
  • #13: 16’ Too often “Quick and Dirty” wins over “The only way to go fast, is to go well” Do you know who says this? Yes. Uncle Bob! The guy w/ the Clean Code, the Clean Architecture etc. The guy that has given me this bracelet. A bracelet to help me to always write the best code I possible can. A bracelet that each time I wan to do something quick and dirty will say to me “No you wont!” The problem is that not everyone has such a bracelet. People are going to forget these rules when they are under pressure to deliver one screen a day. Fast! Does it work? Don’t think, move to the next one! Its simple to forget! So what do we do? What do we do to get a minimum level of quality, that can sustain the project over time?
  • #14: You have some people that review the code and check if rules are followed!
  • #15: 19’ Two guys who are going to review everyone’s code to check if we have the best practices followed, if we have a good SoC, if arch is followed, and if there are places where significant improvements could be done by applying Design Patterns / SOLID Principles or other principles…
  • #16: no circular dependencies – achieved through You put in a structure through your design in a way that it is more difficult to write bad code than code which follows your design You put in your design the constraints. These may make your design to be more closed, less generic, but these are compromises worth doing to achieve consistency through structure
  • #17: 22’ - Enforces Separation of Concern! - Libraries can be used for any kind of applications. We are not interested in building any kid of application, we are interested in building THIS specific application
  • #19: 26’ Encapsulates ALL data access concerns Assures a consistent way to do data access  any component that has to access data has to use a IRepository or an IUnitOfWork Constraints SoC: DA from BLL
  • #21: There is no other way to get an implementation of the IRepository than DI - IRepository used to get data for read-only - Light implementation that can only be obtained through DI - Returns IQueriable<T> - Central place for all queries to the database Testable code No need to pass IRepository as parameters!
  • #23: The UnitOfWork can only be created through this factory method on the repository The UnitOfWork is in an using statement. It has a very well defined scope It is not to be passed as parameters to methods
  • #25: 32’
  • #26: The EF edmx is in the DataModel assembly The tt could be modified that it automatically generates the Context.tt which we have moved in the DbContextProvider assembly We could even take out from the VS Solution the DbContextProvider project if the Context.tt generate is triggered by the SalesEntities.tt and a post build event of the DataModel assembly also builds the DbContextProvider.csproj
  • #27: 39’
  • #28: 39’
  • #29: Enforces Dependency Injection through Constructor only - By hiding the underlying DI Container it makes that the configuration of it can ONLY be done at app startup through annotations or conventions
  • #30: - Enforces Dependency Injection through Constructor only - By hiding the underlying DI Container it makes that the configuration of it can ONLY be done at app startup through annotations or conventions
  • #31: 44’ Dependencies are visible in the constructor Dependencies are on interfaces ONLY  Loose Coupled code  testable code Dependencies are visible, so we can see classes that have too many dependencies –> poor cohesion  refactor to loose coupling The Implementation depends on INTERFACES of other services it uses and on DTOs which are paramenters
  • #32: 48’30”
  • #33: 49’
  • #35: 51’
  • #36: 54’
  • #38: A question I always get
  • #39: - Technical / strategic debt can be done bellow the line No Design, no trade-off: no matter how less attention I will pay to the design I will still go slow. I am impeded by the mess. Less quality -> less options -> more unexpected things -> slower you are Design: I can make the trade-off - Red team productivity NEVER decreases. See above chart with productivity going to 0. - It is important to know where you are. As long as you are under the line you may take technical debt but you must be aware! To be able to keep it under control - When not pay attention to design: - Prj finishes before the intersection point: prototype, throw away, PoC - CHALLENGE: unaware of having bad code or taking too big technical debt. It takes us by surprise - By being on the blue line with our prj most of the times we have done a great job in making our customers/managers not to trust us!
  • #40: - When does quality pay off? All projects have a slower start and then the efficiency increases. The project reaches an healthy productivity rate after the design payoff line Interesting aspects about intersection point Prj finishes before the intersection point: prototype, throw away, PoC Technical / strategic debt can be done bellow. - Cannot be done above: even if you pay less attention/effort on quality you will still need TOO much time to add a feature and the quality still drops - less quality  slower you are Above the line we were in the initial example, but without knowing it! CHALLENGE: unaware of having bad code or taking too big technical debt. It takes us by surprise I will show how by doing GOOD unit tests you can keep this under control by having indicators of when your quality drops By being on the blue line with our prj most of the times we have done a great job in making our customers/managers not to trust us! It is important to know where you are. As long as you are under the line you may take technical debt but you must be aware! To be able to keep it under control Good UT can help us knowing when our quality drops and we sleep over the line
  • #41: Begin 55’ All projects have a slower start and then the efficiency increases. The project reaches an healthy productivity rate after the design payoff line
  • #42: Begin: 52’