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 Consistency through Application Infrastructure Slide 1 Enforce Consistency through Application Infrastructure Slide 2 Enforce Consistency through Application Infrastructure Slide 3 Enforce Consistency through Application Infrastructure Slide 4 Enforce Consistency through Application Infrastructure Slide 5 Enforce Consistency through Application Infrastructure Slide 6 Enforce Consistency through Application Infrastructure Slide 7 Enforce Consistency through Application Infrastructure Slide 8 Enforce Consistency through Application Infrastructure Slide 9 Enforce Consistency through Application Infrastructure Slide 10 Enforce Consistency through Application Infrastructure Slide 11 Enforce Consistency through Application Infrastructure Slide 12 Enforce Consistency through Application Infrastructure Slide 13 Enforce Consistency through Application Infrastructure Slide 14 Enforce Consistency through Application Infrastructure Slide 15 Enforce Consistency through Application Infrastructure Slide 16 Enforce Consistency through Application Infrastructure Slide 17 Enforce Consistency through Application Infrastructure Slide 18 Enforce Consistency through Application Infrastructure Slide 19 Enforce Consistency through Application Infrastructure Slide 20 Enforce Consistency through Application Infrastructure Slide 21 Enforce Consistency through Application Infrastructure Slide 22 Enforce Consistency through Application Infrastructure Slide 23 Enforce Consistency through Application Infrastructure Slide 24 Enforce Consistency through Application Infrastructure Slide 25 Enforce Consistency through Application Infrastructure Slide 26 Enforce Consistency through Application Infrastructure Slide 27 Enforce Consistency through Application Infrastructure Slide 28 Enforce Consistency through Application Infrastructure Slide 29 Enforce Consistency through Application Infrastructure Slide 30 Enforce Consistency through Application Infrastructure Slide 31 Enforce Consistency through Application Infrastructure Slide 32 Enforce Consistency through Application Infrastructure 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 Consistency through Application Infrastructure

Download to read offline

When projects do fail for reasons that are primary technical, the reason is often uncontrolled complexity. The complexity goes out of hand when the code lacks structure. In large software projects where many developers work on the same code base one of the biggest challenge 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 session I will show how we can achieve consistency through structure, rather then 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
  • Be the first to like this

Enforce Consistency through Application Infrastructure

  1. 1. https://onCodeDesign.com/DevTalks2018 Enforce Consistency through Application Infrastructure Florin Coroș .com www.iQuarc.com | www.InfiniSwiss.com | onCodeDesign.com florin.coros@iquarc.com @florincoros
  2. 2. https://onCodeDesign.com/DevTalks2018 About me @florincoros Co-Founder & Partner Partner .com Co-Founder & Partner
  3. 3. https://onCodeDesign.com/DevTalks2018 Why Is Consistency the Key? 3
  4. 4. https://onCodeDesign.com/DevTalks2018 Impeded by Others’ Code? 4
  5. 5. https://onCodeDesign.com/DevTalks2018 Different Solutions to the Same Problem 5
  6. 6. https://onCodeDesign.com/DevTalks2018 Which one is the ONE? 6
  7. 7. https://onCodeDesign.com/DevTalks2018 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. https://onCodeDesign.com/DevTalks2018 Managing Complexity when projects do fail for reasons that are primarily technical, the reason is often uncontrolled complexity 8
  9. 9. https://onCodeDesign.com/DevTalks2018 Controlling the Complexity uniqueness consistency 9
  10. 10. https://onCodeDesign.com/DevTalks2018 Rules Are Easy to Ignore Quick and Dirty vs The only way to go fast, is to go well! 10
  11. 11. https://onCodeDesign.com/DevTalks2018 Quality through Discipline 11
  12. 12. https://onCodeDesign.com/DevTalks2018 Seniors May Be Overwhelmed with Review 12
  13. 13. https://onCodeDesign.com/DevTalks2018 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. https://onCodeDesign.com/DevTalks2018 Assure Consistency in Using External Library by Hiding It Exception Wrappers Decorators <<Interface>> API Interfaces<<static class>> Log +LogError() +LogWarining() 14
  15. 15. https://onCodeDesign.com/DevTalks2018 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 15
  16. 16. https://onCodeDesign.com/DevTalks2018 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 16
  17. 17. https://onCodeDesign.com/DevTalks2018 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 17
  18. 18. https://onCodeDesign.com/DevTalks2018 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); } ... } 18
  19. 19. https://onCodeDesign.com/DevTalks2018 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(); } ... } 19
  20. 20. https://onCodeDesign.com/DevTalks2018 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; } } 20
  21. 21. https://onCodeDesign.com/DevTalks2018 Create Development Patters in how Data is Accessed 21
  22. 22. https://onCodeDesign.com/DevTalks2018 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 22
  23. 23. https://onCodeDesign.com/DevTalks2018 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 23
  24. 24. https://onCodeDesign.com/DevTalks2018 DIP to Move OnSave & OnLoad Logic out of Data Access <<Interface>> TDataModel IEntityInterceptor +OnLoad() +OnSaving() <<Interface>> TDataModel IDbContextFactory +CreateContext() DbContextFactoryUnitOfWork Repository 24
  25. 25. https://onCodeDesign.com/DevTalks2018 AppBoot: DI Abstractions & Type Descovery <<Attribute>> ServiceAttribute IModule <<Interface>> TDataModel IEntityInterceptor +OnLoad() +OnSaving() <<Interface>> TDataModel IRepository Database <<DTO>> Customer<<DTO>> Order<<DTO>> Person DbContextFactoryUnitOfWork Repository <<Interface>> TDataModel IUnitOfWork 25
  26. 26. https://onCodeDesign.com/DevTalks2018 AppBoot Enforces 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 26
  27. 27. https://onCodeDesign.com/DevTalks2018 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(); } 27
  28. 28. https://onCodeDesign.com/DevTalks2018 Patters forCreating Services thatDepend Only onInterfaces [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) { ... } } 28
  29. 29. https://onCodeDesign.com/DevTalks2018 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. https://onCodeDesign.com/DevTalks2018 Design PatternslikeCompositionorChain of Responsibility30
  31. 31. https://onCodeDesign.com/DevTalks2018 Patters in How Dependencies are Created 31
  32. 32. https://onCodeDesign.com/DevTalks2018 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 onCodeDesign.comtraining 32
  33. 33. https://onCodeDesign.com/DevTalks2018 Florin Coroș Co-founder & Partner, iQuarc www.iquarc.com Co-founder & Partner, InfiniSwiss www.infiniswiss.com .com email: florin.coros@iquarc.com blog: onCodeDesign.com tweet: @florincoros

When projects do fail for reasons that are primary technical, the reason is often uncontrolled complexity. The complexity goes out of hand when the code lacks structure. In large software projects where many developers work on the same code base one of the biggest challenge 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 session I will show how we can achieve consistency through structure, rather then 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

32

On Slideshare

0

From embeds

0

Number of embeds

0

Actions

Downloads

0

Shares

0

Comments

0

Likes

0

×