enforce consistency through application infrastructure - florin coros

36
@ITCAMPRO #ITCAMP16 Community Conference for IT Professionals Enforce Consistency through Application Infrastructure Florin Coros www.rabs.ro | www.iquarc.com | onCodeDesign.com [email protected] @florincoros

Upload: itcamp

Post on 16-Apr-2017

916 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals

Enforce Consistency through

Application Infrastructure

Florin Coros

www.rabs.ro | www.iquarc.com | onCodeDesign.com

[email protected]

@florincoros

Page 2: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals

Many thanks to our sponsors & partners!

GOLD

SILVER

PARTNERS

PLATINUM

POWERED BY

Page 3: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals

About me

@florincoros

Founder & Partner

Partner

Partner

.com

Page 4: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals

Many thanks to our sponsors & partners!

GOLD

SILVER

PARTNERS

PLATINUM

POWERED BY

Page 5: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 5

Why Consistency is Key?

Page 6: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 6

Impeded by Others Code?

Page 7: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 7

Different Solutions to the Same Problem

Page 8: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 8

Which one is the ONE?

Page 9: Enforce Consistency through Application Infrastructure - Florin Coros

@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

Page 10: Enforce Consistency through Application Infrastructure - Florin Coros

@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

Page 11: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 11

Controlling the Complexity

uniqueness consistency

Page 12: Enforce Consistency through Application Infrastructure - Florin Coros

@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!

Page 13: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 13

Quality through Discipline

Page 14: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 14

Seniors May Be Overwhelmed with Review

Page 15: Enforce Consistency through Application Infrastructure - Florin Coros

@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

Page 16: Enforce Consistency through Application Infrastructure - Florin Coros

@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

Page 17: Enforce Consistency through Application Infrastructure - Florin Coros

@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

Page 18: Enforce Consistency through Application Infrastructure - Florin Coros

@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();

}

...

} \iQuarc\DataAccess

Page 19: Enforce Consistency through Application Infrastructure - Florin Coros

@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

Page 20: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 20

Patterns for Read-Only datapublic 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);}

...}

Page 21: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 21

Enforce Construction of Unit of Workinternal 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;

}

}

Page 22: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 22

Patterns for Read-Write datapublic 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();

}...

}}

Page 23: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 23

Create Development Patters in how Data is Accessed

Page 24: Enforce Consistency through Application Infrastructure - Florin Coros

@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

Page 25: Enforce Consistency through Application Infrastructure - Florin Coros

@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

DbContextFactoryUnitOfWorkRepository

Page 26: Enforce Consistency through Application Infrastructure - Florin Coros

@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()

Database

<<DTO>>

Customer<<DTO>>

Order <<DTO>>

Person

DbContextFactoryUnitOfWorkRepository

Page 27: Enforce Consistency through Application Infrastructure - Florin Coros

@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

DbContextFactoryUnitOfWorkRepository

<<Interface>>

TDataModel

IUnitOfWork

Page 28: Enforce Consistency through Application Infrastructure - Florin Coros

@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

}

}

\iQuarc\AppBoot

Page 29: Enforce Consistency through Application Infrastructure - Florin Coros

@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();}

Page 30: Enforce Consistency through Application Infrastructure - Florin Coros

@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){

...}

}

Page 31: Enforce Consistency through Application Infrastructure - Florin Coros

@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;

}...}

Page 32: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 32

Design Patterns like Composition or Chain of Responsibility

Page 33: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 33

Development Patters in How Dependencies are Created

Page 34: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals 34

No References Between Modules -> Enforce Constraints

<<Attribute>>

ServiceAttribute

+ ServiceAttribute()+ServiceAttribute(Type contract)+ ServiceAttribute(Type t, Lifetime lifetime)

Page 35: Enforce Consistency through Application Infrastructure - Florin Coros

@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

\iQuarc\Code-Design-Training

Page 36: Enforce Consistency through Application Infrastructure - Florin Coros

@ITCAMPRO #ITCAMP16Community Conference for IT Professionals

Florin CorosCo-founder & Partner, iQuarc www.iquarc.com

Partner, Infiniswiss www.infiniswiss.com

.com

email: [email protected]

blog: onCodeDesign.com

tweet: @florincoros