Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

Enforce Consistentcy with Clean Architecture Slide 1 Enforce Consistentcy with Clean Architecture Slide 2 Enforce Consistentcy with Clean Architecture Slide 3 Enforce Consistentcy with Clean Architecture Slide 4 Enforce Consistentcy with Clean Architecture Slide 5 Enforce Consistentcy with Clean Architecture Slide 6 Enforce Consistentcy with Clean Architecture Slide 7 Enforce Consistentcy with Clean Architecture Slide 8 Enforce Consistentcy with Clean Architecture Slide 9 Enforce Consistentcy with Clean Architecture Slide 10 Enforce Consistentcy with Clean Architecture Slide 11 Enforce Consistentcy with Clean Architecture Slide 12 Enforce Consistentcy with Clean Architecture Slide 13 Enforce Consistentcy with Clean Architecture Slide 14 Enforce Consistentcy with Clean Architecture Slide 15 Enforce Consistentcy with Clean Architecture Slide 16 Enforce Consistentcy with Clean Architecture Slide 17 Enforce Consistentcy with Clean Architecture Slide 18 Enforce Consistentcy with Clean Architecture Slide 19 Enforce Consistentcy with Clean Architecture Slide 20 Enforce Consistentcy with Clean Architecture Slide 21 Enforce Consistentcy with Clean Architecture Slide 22 Enforce Consistentcy with Clean Architecture Slide 23 Enforce Consistentcy with Clean Architecture Slide 24 Enforce Consistentcy with Clean Architecture Slide 25 Enforce Consistentcy with Clean Architecture Slide 26 Enforce Consistentcy with Clean Architecture Slide 27 Enforce Consistentcy with Clean Architecture Slide 28 Enforce Consistentcy with Clean Architecture Slide 29 Enforce Consistentcy with Clean Architecture Slide 30 Enforce Consistentcy with Clean Architecture Slide 31 Enforce Consistentcy with Clean Architecture Slide 32 Enforce Consistentcy with Clean Architecture Slide 33
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

0 Likes

Share

Download to read offline

Enforce Consistentcy with Clean Architecture

Download to read offline

When projects fail for reasons that are primary technical, the reason is often uncontrolled complexity. The complexity goes out of hand when the code lacks structure, when it lacks Clean Architecture. In large software projects where many developers work on the same code base one of the biggest challenges is to get consistency in code, to create development patterns for common problems, so you can control the complexity and size of the system.

In this presentation I will show how we can achieve consistency through structure, rather than relying on discipline only. We will look at some basic building blocks of an application infrastructure which will enforce the way dependencies are created, how dependency injection is used or how separation of the data access concerns is enforced.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Enforce Consistentcy with Clean Architecture

  1. 1. Florin Coroș florin@onCodeDesign.comwww.onCodeDesign.com/training Enforce Consistency with Clean Architecture
  2. 2. Co-Founder & Partner About me @florincoros Partner https://onCodeDesign.com/training Founder & Partner
  3. 3. Why Is Consistency the Key? 3
  4. 4. Impeded by Others’ Code? 4
  5. 5. Different Solutions to the Same Problem 5
  6. 6. Which one is the ONE? 6
  7. 7. Cost of Change Wrong approach consistently repeated in all of the application screens vs Uniquely new approach in all of the application screens 7
  8. 8. Managing Complexity when projects do fail for reasons that are primarily technical, the reason is often uncontrolled complexity 8
  9. 9. Controlling the Complexity uniqueness consistency 9
  10. 10. Rules Are Easy to Ignore Quick and Dirty vs The only way to go fast, is to go well! 10
  11. 11. Quality through Discipline 11
  12. 12. Seniors May Be Overwhelmed with Review 12
  13. 13. 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 13
  14. 14. Assure Consistency with Clean Architecture http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html Apply Dependency Inversion Principle 14
  15. 15. Ensure Consistency with Clean Architecture15 <<interface>><<interface>> ILogger +LogError() Logger +LogError() <<public interface>><<public interface>> ILogger +LogError() <<Internal class>><<Internal class>> Logger +LogError()
  16. 16. Ensure Consistency with Clean Architecture16 <<Stereotype>><<Stereotype>> Exception Wrappers <<public Interface>> <<public Interface>> API Interfaces <<Internal class>><<Internal class>> Decorators
  17. 17. Encapsulate Data Access Concerns iQuarcDataAccess <<Interface>> TDataModel <<Interface>> TDataModel IRepository +GetEntities<TDataModel>() <<Interface>> TDataModel <<Interface>> TDataModel IUnitOfWork +GetEntities<TDataModel>() +SaveChanges() Database EfRepositoryEfRepository EfRepositoryEfRepository <<Stereotype>><<Stereotype>> <<DTO>><<DTO>> Order <<DTO>><<DTO>> Person <<Stereotype>> <<DTO>> Order <<DTO>> Person 17 [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(); } ...
  18. 18. 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 18
  19. 19. 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); } ... 19
  20. 20. 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(); } ... 20
  21. 21. 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; } } 21
  22. 22. Create Development Patters In How Data is Accessed 22
  23. 23. <<Interface>> TDataModel <<Interface>> TDataModel IRepository +GetEntities<TDataModel>() <<Interface>> TDataModel <<Interface>> TDataModel IUnitOfWork +GetEntities<TDataModel>() +SaveChanges() Database EfRepositoryEfRepository EfRepositoryEfRepository <<Stereotype>><<Stereotype>> <<DTO>><<DTO>> Order <<DTO>><<DTO>> Person <<Stereotype>> <<DTO>> Order <<DTO>> Person Enforce Separation of Data Access Concerns23
  24. 24. <<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 DIP to Enforce Separation of Data Access Concern 24
  25. 25. <<Interface>> TDataModel <<Interface>> TDataModel IEntityInterceptor +OnLoad() +OnSaving() <<Interface>> TDataModel <<Interface>> TDataModel IDbContextFactory +CreateContext() <<DTO>><<DTO>> Customer<<DTO>><<DTO>> Order<<DTO>><<DTO>> Person <<DTO>> Customer<<DTO>> Order<<DTO>> Person UnitOfWork Repository UnitOfWork Repository DbContextFactory DIP to Move OnSave & OnLoad Logic out of Data Access 25
  26. 26. AppBoot: DI Abstractions & Type Discovery 26 <<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
  27. 27. AppBoot Separates DI Configuration from DI Use27 iQuarcAppBoot <<Attribute>><<Attribute>> ServiceAttribute +LogError() Bootstrapper +Run() <<Internal>><<Internal>> DependencyContainerAdapter 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 } }
  28. 28. Patters forCreating Services thatDepend Only onInterfaces [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) { ... } } 28
  29. 29. 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; } ... } 29
  30. 30. Design PatternslikeCompositionorChain of Responsibility30
  31. 31. Patters in How Dependencies are Created31
  32. 32. /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 github.com/onCodeDesign onCodeDesign.com/training 32 <<Attribute>><<Attribute>> ServiceAttribute RepositoryImpl + GetEntities<T>() : IQueriable() + SaveChanges()
  33. 33. 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

When projects fail for reasons that are primary technical, the reason is often uncontrolled complexity. The complexity goes out of hand when the code lacks structure, when it lacks Clean Architecture. In large software projects where many developers work on the same code base one of the biggest challenges is to get consistency in code, to create development patterns for common problems, so you can control the complexity and size of the system. In this presentation I will show how we can achieve consistency through structure, rather than relying on discipline only. We will look at some basic building blocks of an application infrastructure which will enforce the way dependencies are created, how dependency injection is used or how separation of the data access concerns is enforced.

Views

Total views

41

On Slideshare

0

From embeds

0

Number of embeds

1

Actions

Downloads

0

Shares

0

Comments

0

Likes

0

×