WPF Commands – A Pattern that Works

Using commands in WPF can be frustrating. Having so many different ways to do commanding in WPF leads to some confusion. There are multiple ways to wire up commands that are equally correct, though some patterns are cleaner than others.

Below is a pattern that works.

Create static property to expose command

Making the command a property rather than a variable makes the syntax in XAML a bit cleaner.  Using RoutedUICommand allows setting the text for the command. This is useful if you want to use the command in multiple places.

Here’s code for creating the command, e.g. in a MainWindow class:

private static RoutedUICommand _pressMeCommand = new RoutedUICommand("Press Me", "PressMe", typeof(MainWindow));
public static RoutedUICommand PressMeCommand
{
    get { return _pressMeCommand; }
}

Add CanExecute and Executed handlers

Add code in code-behind (or ViewModel) for handlers. Below, we have private handlers in MainWindow. In this example, we have a boolean indicating whether the command can be executed. You could also put the logic directly in CanExecute, if it’s not used elsewhere.

private void PressMe_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = CowboyCanTalk;
}

private void PressMe_Executed(object sender, ExecutedRoutedEventArgs e)
{
    MessageBox.Show("Howdy howdy I'm a cowboy");
}

Set up command binding

You can do this from code or XAML.  Doing it in XAML is perhaps a bit cleaner. Below is an example of binding the above command to its handlers from XAML (for MainWindow). Note that we can just use command name instead of {x:Static syntax because we made the command a property.

<Window.CommandBindings>
    <CommandBinding Command="local:MainWindow.PressMeCommand"
                    CanExecute="PressMe_CanExecute"
                    Executed="PressMe_Executed"/>
</Window.CommandBindings>

 

Wire up a button

Below, we wire a button up to the command.  You could just set Content to text directly. This would be fine to do and is simpler than what we’re doing below. But putting the text into the RoutedUICommand is helpful if you use the command in more than one place (since you specify text in just one place—in the command). And menu items automatically pick up the command text. (NOTE: If you used this pattern for Content regularly, you could just put it in a style to hide the complexity).

<Button Command="local:MainWindow.PressMeCommand"
        Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" />

Wire up a menu item

Below, we wire up a menu item in a context menu to the same command. Note that here we do have to use the x:Static syntax. But also note that we don’t need to specify text for the menu item—it comes from the RoutedUICommand.

<Window.ContextMenu>
    <ContextMenu>
        <MenuItem Command="{x:Static local:MainWindow.PressMeCommand}" />
    </ContextMenu>
</Window.ContextMenu>

Bottom line

  • We used RoutedUICommand so that we could attach text to the command and avoid specifying text for both button and menu item
  • Binding in XAML is a (tiny) bit less code than doing it in code-behind

Other thoughts

  • You could also use a DelegateCommand pattern, passing in lambdas for both CanExecute and Executed. Use of a DelegateCommand is common in MVVM architectures.

 

 

Object Disposal and BackgroundWorker Object in .NET

Here are a few notes about best practices related to:

  • IDisposable and an object’s Dispose() method
  • The using statement
  • Disposal of BackgroundWorker objects

(NOTE: BackgroundWorker object is no longer the preferred mechanism for doing work on a background thread in C#, given that the language supports task-basked asynchrony with the async/await constructs. However, many legacy applications still make use of the BackgroundWorker class).

Q: What’s the goal of the using statement and IDisposable (Dispose) interface?

A: (short) To tell an object when it can clean up unmanaged resources that it might be hanging onto

A: (longer)

  • .NET code can make use of managed resources (e.g. instantiate another .NET object) or unmanaged resources (e.g. open a file to read from it)
  • Managed resources are released by the garbage collector (GC) automatically
    • Note that this is non-deterministic, i.e. you can’t predict when an object will be GC’d
  • To release an unmanaged resource, code typically follows this pattern:
    • Release resource in finalizer  (~ syntax).  Finalizer called during GC, so unmanaged resource is then released when object is being GC’d
    • Optionally, can support IDisposable (Dispose method)
      • Client calls Dispose before object is GC’d to released unmanaged resource earlier than normal GC
      • Allows for deterministic destruction
      • using statement automates calling of Dispose on an object
    • Classes implementing Dispose will still get GC’d normally at a later time
      • If Dispose was called first, code typically tells GC not to call its finalizer, since it’s already done stuff done by the finalizer (GC.SuppressFinalization)
      • If client failed to call Dispose, finalizer runs normally, so unmanaged resources then get cleaned up before GC
    • Objects with finalizers take a little bit longer to be GC’d
    • Here’s how IDispose is typically implemented – http://csharp.2000things.com/2011/10/11/430-a-dispose-pattern-example/

 

Q: When should I use the using statement?

A: Typically, you should use the using statement to invoke Dispose on any object that implements IDisposable

 

Q: What happens if I don’t call Dispose or use the using statement?

A: (short) Unmanaged resources are (typically) released a bit later than they otherwise would be

A: (longer)

  • If you don’t call Dispose on an object that implements IDisposable, it typically hangs onto unmanaged resources until it is GC’d and then releases them
  • Depending on the type of resource, the first object may block access to the resource until it’s released
  • Failing to use using (or call Dispose) typically doesn’t lead to a memory leak. Rather, it just means that resources are released a bit later

 

Q: Should I use a using statement for a BackgroundWorker object?

A: (short) Yes, since BackgroundWorker has Dispose method (although calling Dispose doesn’t actually do anything)

A: (longer)

  • It’s okay to use using on BackgroundWorker, since it does implement IDisposable
  • BackgroundWorker, however, doesn’t actually do anything when Dispose is called.  Its parent class, Component, detaches from its ISite container, but this is only relevant in Windows Forms.
  • Calling Dispose does suppress finalization, which means that the BackgroundWorker will be GC’d a little bit sooner.  This is reason enough to use using on the BackgroundWorker.
  • The using statement for a BackgroundWorker does nothing with the BackgroundWorker’s event handlers (i.e. it doesn’t detach any event handlers)

 

Q: Should I detach event handlers in the handler for RunWorkerCompleted?

A: (short) No, you (typically) don’t need to explicitly detach event handlers for a BackgroundWorker

A: (longer)

  • In .NET, if two objects reference each other, but no other “root” object references either of them, they do both get garbage collected
  • If we have a WPF form that has a class-level reference to a BackgroundWorker
    • Assume that we instantiate the BackgroundWorker when user does something on the form and attach handlers (methods in form) to that instance
    • Form now has ref to BackgroundWorker (class-level ref) and BW has ref to form (via the handlers)
    • When form closes, if main application no longer has a reference to the form, both the form and the BackgroundWorker will be properly garbage collected even though they reference each other
  • You do need to detach handlers if you have a BackgroundWorker that is meant to live longer than the object that owns the handlers
    • g. If we had an application-level BackgroundWorker and forms that attached handlers to its DoWork or RunWorkerCompleted events.  If the BW was meant to live after the form closes, you’d want to have the form detach its handlers when it closed.

 

 

String Properties in ADO.NET Entity Data Model

(NOTE: This is Model First development in Entity Framework–start with a data model in the Entity Framework Designer and then generate database schema from the model).

When you add a scalar property of type string to an entity data model, you can fill in the values of several other properties within Visual Studio.

  • Fixed Length – (None), True, False
  • Max Length – (None), value, Max
  • Unicode – (None), True, False

stringprop

What does a value of (None) mean for these properties (when generating SQL Server Database from model)?

  • Fixed Length – (None) equivalent to False
  • Max Length – (None) equivalent to Max
  • Unicode – (None) equivalent to True

Here’s how choices for these properties map to SQL Server data types:

  • Fixed=True, Max=20 – nchar(20)
  • Fixed=(None), Max=20 – nvarchar(20)
  • Fixed=False, Max=20 – nvarchar(20)
  • Fixed=(None), Max=(None) – nvarchar(max)
  • Fixed=True, Max=(None) – nchar(4000)
  • Fixed=False, Max=(None) – nvarchar(max)
  • Fixed=(None), Max=Max – nvarchar(max)
  • Fixed=True, Max=Max – nchar(4000)
  • Fixed=False, Max=Max – nvarchar(max)
  • Fixed=(None), Max=20, Unicode=True – nvarchar(20)
  • Fixed=(None), Max=20, Unicode=False – varchar(20)

This means that if you just pick String as the type and set nothing else, you’ll get nvarchar(max) as the SQL Server type.

NOTE: The value of 4,000 is being used because the maximum length of a fixed length string in SQL Server is 4,000 characters (8,000 bytes when encoded as UTF-16).

 

Count Total Rows while Paging and Avoid Two Queries

This is well covered in many other places, but I’m posting on my own blog so that I can more easily find this trick.

You can do paging in SQL Server 2012 and later using the OFFSET-FETCH syntax. This is useful for returning a single page’s worth of records from a larger (sorted) set of records. To count the total number of records, however, you’d normally do a second query. The T-SQL below shows how to do a total count as part of the query that returns the page in question. The count is repeated for every record, but it avoids having to do two queries.

select FirstName, LastName, COUNT(*) over () as TotalCount
  from Person
  where LastName like 'mc%'
  order by LastName, FirstName
  offset 500 rows
  fetch next 100 rows only

Here’s what the output looks like, returning records 501-600 out of 1,968 records having a last name that starts with “Mc”.

161109-1

SQL Server -Dump Info on Keys

Here’s a short stored procedure that could be useful when trying to understand a SQL Server database.

Let’s say that you have a simple schema like the one below. Person has GroupID as a foreign key (Group.GroupID), meaning that a person belongs to a single group. A person can also have multiple contact records, so PersonContact has a foreign key indicating which person the contact is for.

Keys

In a simple schema like this, you can quickly see the two relationships. You can also see some of this by looking at the Person table in Management Studio, under Columns and Keys. In the diagram below, we see that GroupID is a foreign key and, based on the naming convention, we infer that the corresponding primary key is in the Group table.

MgmtStudio

This notation relies on the naming convention used for the FK_Person_Group relationship. Also, while looking at the Person table, we’re unable to see which tables might contain foreign keys that refer to the primary key in the Person table.

Below is a simple stored procedure that dumps out all relationships that a specified table participates in. That is, given a table, it tells you:

  • All foreign keys that reference the specified table’s primary key
  • All foreign keys in the specified table and where the corresponding primary key is located
-- Given specified table, show all PK/FK relationships.  Show:
--   1) All foreign keys that reference this table's primary key
--   2) All foreign keys in this table and which table contains primary key
create procedure uKeys
(
	@TableName varchar(255)
)
as
begin
select tfk.name as PKTable, cfk.name as PKColumn, tpk.name as FKTable, cpk.name as FKColumn from sys.foreign_key_columns fk
  inner join sys.tables as tpk on fk.parent_object_id=tpk.object_id
  inner join sys.columns as cpk on fk.parent_object_id=cpk.object_id and fk.parent_column_id=cpk.column_id
  inner join sys.tables as tfk on fk.referenced_object_id=tfk.object_id
  inner join sys.columns as cfk on fk.referenced_object_id=cfk.object_id and fk.referenced_column_id=cfk.column_id
  where (tpk.name = @TableName) or (tfk.name = @TableName)
  order by PKTable, PKColumn, FKTable, FKColumn
end;

With this stored proc in place, you can now do the following in a query window, to ask about the keys for the Person table.

ukeys 'Person'

You’ll get some nice output that shows information about all of the relationships for the Person table.

Output

This is a simple example, but this procedure is considerably more useful when you’re dealing with very large databases, where you have a large number of tables and it’s not easy to see all of the relationships for a particular table.

Addendum: There’s already a built-in stored procedure in SQL Server that does basically the same thing (though perhaps in not as clean a format). sp_helpconstraint will dump out the same sort of information, as shown below.

sphelpconstraint

That Conference 2016 – From Inception to Production: A Continuous Delivery Story

That Conference 2016, Kalahari Resort, Lake Delton, WI
From Inception to Production: A Continuous Delivery Story
Ian Randall

Day 3, 10 Aug 2016

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2016 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Executive Summary

  • Ian shares best practices of his development group at Pushpay, from inception to deployment

Tell a continuous delivery story in context

  • Pushpay company, SaaS business
  • ACMR Growth – committed monthly revenue stream
  • to $10 million in 3 quarters (5 considered fast)
  • Everyone at Pushpay paid to deliver value to business
    • Code not yet running on production server has no value

Hierarchy

  • Tools (top)
  • People, practices
  • Just culture & blameless postmortems
    • Bottom layer, most important

Our journey begins

  • Idea

Why?

  • Shared vision over the value to the business
  • Talk about why to build it
    • Better than talking about what

Who?

  • Who has conversation?
    • Product
    • QA – must involve QA in initial discussion
      • Can’t just test quality at end
      • “Bake quality in”
      • Build with tester (pairing)
    • Dev

Building a feature

  • Dev – how will I build this thing?
  • QA – how will I break this thing?
    • Very valuable insight
    • “Nobody will ever do that”
    • QA tester writes out what tests should be
    • Then Dev writes unit tests based on this
    • Quality Assistant (not Assurance)

Building a larger feature

  • Long-lived feature branch (git)
    • Delta gets too big
      • Smaller deltas are lower risk
    • No feedback – from user
    • (good) dry code
  • Feature switches (toggles)
    • Small deltas
    • Regular feedback
    • (bad) technical debt
      • Some code duplicatoin
      • But you have to go back later and yank out old code

Pushpay terminology

  • Delta – diff between production server & head of master branch
    • Code no yet running in production
  • Want to keep delta small and contained
  • Shipping in tinier increments, easier to figure out what the cause of the problem is

Feature Switches

  • Configuration per environment
    • Features.config
    • Features.Production.config
    • Features.Sandbox.config

Feature Switches

  • Url manipulation to toggle switches on/off
  • Deliver daily increments of (non-running) code
  • Light up a slice of feature
  • Measure – statsd
  • Re-think road-map to compmlete feature

Womm

  • Works on My Machine
  • Context switching after QA person finds problem
  • Pushpay, turned around
    • Must work on your machine
    • Tester decides this
    • Hand laptop to tester, let them test on the dev machine
    • Best value for company from dev point of view–watch tester break it right in front of them
    • Shortens the DEV/QA cycle
    • Pair testing

Code review

  • Every line of code gets reviewed
  • Code must reviewed and wommed before merging
  • “Roll forwards to victory”

Code Review

  • Do
    • Validate approach
    • Performance, security, operability
    • Cohesion, coupling
    • Be honest
  • Don’t
    • Be rude – e.g. “dude that’s gross”
      • Better – tell coder how you would have done it?
    • Seriously, don’t be rude
    • Sweat the small stuff, like bracing, spaces
      • This stuff is not important

Cross-Pollination

  • Someone else does it all again!
  • Pollination – not necessarily from your cell
  • Might not fully understand the context of your feature

4 Cotinuouses

(1) Continuous Integration

  • Source control
    • PR branch
    • Pushed early, for discussion
  • Build & Test
    • TeamCity does builds, using nUnit for unit testing
    • Integration testing – anything that crosses a boundary

CI – Source Control

  • PR-based workflow
  • Review happens in the PR
  • Everything reviewed

CI – build and test

  • PR Branch: Build, unit test and integration test
  • Merge into master – build, unit test, integration and acceptance test
    • Goes to QA – then rolled back or pushed to production
    • Human decision to push to production
    • Acceptance tests in Selenium – a bit brittle, but have some value
    • Create static Model and push to View, then test
      • If it breaks there, it’s not because of back-end
      • Verified that your site is intact, visually
      • Renders view against snapshot – if diff, either a bug or you accept as new snapshot

(2) Continuous Deployment

  • Automatically build, package and deploy to QA
    • Octopus deploy (great tool)
  • Manually promote package to production
    • One button click (because of Octopus)

(3) Continuous Delivery

  • Operability
  • Value

CD – Operability

  • Exception logging
  • App logging (Log4Net)
  • App metrics (statsd)
    • Measure absolutely everything
  • Incident

CD – Value

  • Add incremental bits of value to the product
    • Need to think – is there maybe value in shipping a portion of the feature?
  • Measuring the effectiveness

(4) Continuous Improvement

  • Actively seeking out opportunities to improve
    • Fix broken windows
    • Leave codebase in better state than when you found it
    • Improve the process

Bots

  • Shipbot, Beebot, Salesbot
    • Many, many, many more
  • @C3PR in action
    • Catalog of little commands
    • People joining PRs together

Just Culture

  • sidney dekker
  • Retributive culture
    • Clarity between acceptable and unacceptable
  • Restorative culture / model
    • Focuses on learning from what went wrong
    • Safe to fail

Fear of breaking things will paralyze an organization

Toyota’s Five Whys

  • Keep asking why until you get to root cause of problem
  • Doesn’t work for Pushpay
    • No single thing that is root cause
    • And often turns into “who”

Blameless Post-Mortems

  • Talk about how to stop the thing from happening again
  • When?
    • When there is an opportunity
    • Often, after break to production
    • Or even when something brings QA server down
  • How?
    • If we had a meeting, the loudest person in the room would do the most talking
    • So we do this asynchronously in a Wiki
    • Coordinated in slack channel #morgue
    • Co-ordinated with person closest to the incident
  • What?
    • Four sections in report
      • Scenario and impact
      • Timeline – write in real-time
      • Discussion
      • Mitigation – make sure this type of thing won’t happen again
        • Actionable ticket in Jira, highest priority possible
        • Slipping feature is better than having the incident happen again

Fault

  • Easy for manager to say to staff–when stuff happens, it’s not your fault
  • Much harder to go to CEO and say that stuff just happens
    • Board reads every post-mortem

That Conference 2016 – Clean Architecture: Patterns, Practices, and Principles

That Conference 2016, Kalahari Resort, Lake Delton, WI
Clean Architecture: Patterns, Practices, and Principles
Matthew Renze – @matthewrenze

Day 3, 10 Aug 2016

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2016 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Executive Summary

  • A whirlwind overview of domain-centric architecture and discussion of its merits
  • Overview of CQRS architectures (Command and Query Responsibility Segregation)
  • Brief mention of microservices architectures

Story – Tale of two architecures

  • John/Jane, same expertise
  • Hire them to design two buildings, same purpose
  • John
    • Superstar, creates the architecture, hands off to builder
  • Jane
    • Starts by talking to inhabitants and crews
    • Then involved during construction, helping implement
    • Tweaks plan as necessary
  • Captures essence of difference between clean architecture and traditional

About Me

  • Consultant
  • Pluralsight
  • Msft MVP

Focus

  • Enterprise architecture
  • Line-of-business applications
  • Modern equivalent of 3-layer
  • Will talk about 6 key ideas

What is software architecture?

  • High-level – higher level than the code
  • Structure
  • Layers – vertical partitions of system
  • Components – sub-divisions of layers, or horizontal
  • Relationships – how wired

Levels of architectural abstraction

  • System
  • Sub-systems
  • Layers
  • Components
  • Classes
  • Data and methods

Messy vs. Clean Architecture

  • Bad – like spaghetti
  • Good – lasagna
    • Nice layers

What is Bad Architecture?

  • Complex – accidental
  • Inconsistent
  • Incoherent – things don’t fit
  • Rigid – not adaptible
  • Brittle
  • Untestable
  • Unmaintainable

Clean Architecture

  • Simple
  • Understandable – easy to reason about
  • Flexible
  • Emergent
  • Testable
  • Maintainable – easier to maintain over lifetime

Clean architecture

  • Architecture that is designed for inhabitants of the architecture
    • Not for architect
    • Or for machine
  • Start designing architecture for inhabitants
    • This is the primary concern
    • Everything else is secondary

Why is clean architecture important?

  • Cost/benefit
  • Minimize cost to maintain
    • Good to optimize for maintainability
    • Since most cost is spent during maintenance
  • Maximize business value

Decisions

  • Context is king
    • Answer always depends on context
  • All decisions are a tradeoff
  • Use your best judgment

Domain-Centric Architecture

  • Heliocentric was more elegant model of the solar system

Classic 3-layer architecture

  • Database at central, then data access, business logic

Domain-centric

  • Domain at center
  • Application around that
  • Then Application
  • Database hung off the side

Uncle Bob

  • Most important thing is that the architecture is usable

Essential vs. Detail (e.g. for house)

  • Space is essential
  • Usability is essential
  • Building material is a detail
  • Ornamentation is a detail

Essential vs. Detail (Clean architecture)

  • Domain is essential
    • Domain: series of object models at center
    • Mirrors the mental models of the domain
  • Use cases are essential
    • And users
  • Presentation is a detail
  • Persistence is a detail
    • Can store in relational DB, NoSql, doc DB, etc.

Back to domain-centric diagram

  • What is essential is at the center of the diagram
  • Domain essential
    • At center
    • Everything points towards the domain

Hexagonal architecture

  • Application layer (domain) at center
  • Adapting to presentation
  • Adapting to do input
  • Adapting to persistence

Onion Architecture

  • Domain Model at center
  • Services
  • UI at outer

The Clean Architecture (Uncle Bob’s)

  • Entities at center
  • Use Cases
  • Controllers
  • Outside: Devices, Web, UI, External Interfaces

It’s all the same thing

  • All three of these are fundamentally the same
  • Domain at the center

Why use domain-centric architecture?

  • Pros
    • Focus on essential
    • Less coupling to details
    • Necessary for DDD
  • Cons
    • Change is difficult
    • Requires extra thought
    • Initial higher cost

Application Layer

  • Might embed use cases as high-level logic

What are layers?

  • Levels of abstraction
  • Single-Responsibility
  • Developer roles/skills
  • Multiple implementations

Classic 3-layer architecture

  • Database at bottom
  • Data Access
  • Business Logic
  • UI
  • Users
  • Top layers dependent on layer below it

Modern 4-layer architecture

  • Presentation at top
  • Application below that
  • Domain layer
    • Only domain logic
  • Persistence below application
    • Access to DB
  • Infrastructure below application
    • Access to OS

Application layer

  • Implements use cases
  • High-level application logic
  • Knows about domain layer but not persistence or infrastructure
  • No knowledge of upper layers

Layer Dependencies

  • Dependency inversion
  • Inversion of control
    • Details depend on abstractions
  • Independent deployability
  • Flexibility and maintainability
  • Flow of control
    • Presentation calls Application
    • Persistance calls Application

Example

  • Presentation layer w/controller
  • Application
    • Command dep on IDatabaseContext, IInventoryClient
    • Application–what the users are doing with the system
      • E.g. ICreateSalesCommand
  • Dep on Sale in Domain
    • Domain–objects in system
      • e.g. Sale object
  • Interface in cross-cutting concerns

Why use an application layer?

  • Pros
    • Focus is on use cases
    • Easy to understand
    • Follows DIP – Dependency Inversion Principle
  • Cons
    • Additional cost
    • Requires extra thought
    • What is application logic vs. domain logic ?
    • IoC is counter-intuitive

Commands and Queries

  • Keep separated
  • Command
    • Do something
    • Modifies state
    • Should not return value
  • Queries
    • Answer question
    • Do not modify state
    • Always returns value
  • Why?
    • Avoid side-effects
  • Sometimes odd, exceptions
    • E.g. create record, return it

CQRS Architectures

  • Application layer, separate into two parts
  • Left
    • Queries
    • Data Access
  • Right
    • Commands
    • Domain
    • Persistence
  • Database at bottom
  • Data flow
    • Down through commands
    • Up through queries
  • CQRS is domain architecture done in sensible way

CQRS Type 1 – Single Database

  • Single database, typically NoSQL
  • Persistence layer might be something like EF
  • Queries – stored proc, linq to sql

CQRS Type 2 – Read/Write Databases

  • Command stack leads to Write Database
    • 3NF
  • Read database
    • 1NF, optimized for reads
  • Use “eventually consistent” model to push data across from write to read
  • Orders of magnitude performance improvement over single database
    • Because we mostly do reads, not writes

CQRS Type 3 – Event Sourcing

  • Command stack leads to Event Store
  • Read database under query stack
  • Replay events to get current state of entity (from deltas)
  • State modifications pushed over to Read Database

Type 3 points

  • Complete audit trail
  • Point-in-time reconstruction
  • Replay events
  • Rebuild production database
    • Just by replaying events
  • Only worth doing if you need these features

Why use CQRS?

  • Pros
    • More efficient design
    • Simpler within each stack
      • At expense of inconsistency across stacks
    • Optimized performance
      • Of each side
  • Cons
    • Inconsistent across stacks
      • More complexity
    • Type 2 is more complex
      • Adds consistency model
    • Type 3 might be overkill
      • If you don’t get business value from these features

Functional organization

  • Screaming architecture
    • Architecture should scream the intent of the system
  • Organize architecture around use cases
  • Uncle Bob

Building metaphor

  • House, typical
    • Intent – residential
    • Rooms embody uses–bedroom, kitchen, living room
    • Architecture shows use
  • Look at list of components, rather than architectural diagram
    • Can’t infer intent

Software intent

  • Could organize folders by components (models, views, controllers)
  • Or organize by things
    • Customers, products, vendors

This vs. that

  • Traditional
    • Content, Controllers, Models, Scripts
  • Functional
    • Customer
    • Product

So what?

  • Functional cohesion is more efficient
    • Because it better models how we think about the software

Why use functional organization

  • Pros
    • Spatial locality
    • Easy to navigate
    • Avoid vendor lock-in
  • Cons
    • Lose framework conventions
    • Lose automatic scaffolding
    • Categorical is easier at first

Microservices

Components

  • Horizontal – UI, business, data access
  • Vertical – Sales, Support, Inventory
  • UI presents all vertical pieces as single unified UI

Problem Domain

  • Sales and Support

Single domain model

  • Traditionally, create single domain model
  • E.g. Product on both sides, so we have single Product entity
  • Employee – sales or service
  • Problem
    • Becomes exponentially more difficult

Bounded contexts

  • Sales and support as boundaries
  • Some entities in just Sales
    • Some in Support
    • Some in overlap
  • Then pull apart and have separate models for each context

Microservice architectures

  • Subdivide system
    • Communicate with each other via lightweight mechanisms
  • Bounded contexts
    • Can have one agile team per bounded context
    • Only have to know about one bounded context
  • Small teams
  • Qualities
    • Independent
    • Similar to SOA
    • Independently deploy and scale each microservice
  • Size of microservices
    • Ongoing debate
    • Bounding context maps to microservice
    • So persistence model matches context matches service
    • “Goldilocks” point

Why use microservices?

  • Pros
    • Less cost for large domains
    • Smaller teams
    • Independence
      • Don’t need to know what other teams are doing
  • Cons
    • Only for large domains
      • Overkill for small domains
      • Lot of overhead cost for microservice
    • Higher up-front cost
      • Fault tolerance, latency, load balancing
      • Might start with single system, split when you have multiple bounded contexts
      • – Distributed system costs

Code Demo

  • Solution architecture for simple web site
  • ASP.NET MVC 5
  • Top-level folders
    • Application, Common, Domain, Infrastruccture, Peristence, Presentation
  • Presentation, Sales folder
    • sub-folders Models, Services, views
  • Application layer
    • Sales | Commands, Queries
    • Under Commands, folder for each command
  • Domain layer
    • Fairly thin object model
    • But a small amount of business logic in the objects

Where to go next

  • Patterns of Enterprise Application Architecture – Fowler
  • Bliki has updated stuff
  • Clean Code – Uncle Bob
    • cleancoders.com
    • Great
  • Domain-Driven Design – Evans
    • For complex domains
  • Greg Young, Udi Dahan
    • CQRS event sourcing
  • matthewrenze.com
    • Pluralsight courses as well