(TK-18) Improve implementation of `service` macro

This commit changes the implementation of the `service` macro so
that rather than building up the prismatic graph of functions
first and then reifying the service instances as wrappers around
the graph, we instead reify the service instances first and build
the prismatic graph functions as wrappers around the protocol
instances.  This makes the services look and feel much more
like "normal" protocol reifications; it should alleviate some
of the strange compilation errors that we'd occasionally get
when trying to call functions from the `Service` protocol, etc.

The only API change is to remove the `service-constructor` function
from the `ServiceDefinition` protocol, which shouldn't have many
external implications since this function was an internal implementation
detail.
It seems like you could solve this a different way - instead of providing `instantiate` an `atom` and later dereferencing it, the `instantiate` function could be modified to return the service references along with the compiled graph.  This has the benefit of eliminating mutable state (`service-refs`).

Something like...
```clj
(let [ ...
      [graph-instance services-by-id] (instantiate compiled-graph {:tk-app-context app-context})
```