Taking Control of WCF Slide Deck

Report
Taking Control of WCF
Jay Hill
Patrick Roeper
Presentation Goals
• Take the most common WCF experience and
make it better
– Leverage OO design principles; improve
extensibility, maintainability, testability
– Reduce repetition
• Demonstrate techniques when playing role of:
– Publisher
– Consumer
– Publisher and Consumer
Demo
• Jay is recovering from
star-trek-hand
syndrome
• Occasional accidentalreboot while typing
MethodA(ReqA req)
{
Logger.Log(“Handling ReqA”);
try
{
var result = new ResultA();
result.Name = GetName(req.Id);
result.Email = GetEmail(req.Id);
return result;
}
catch (Exception ex)
{
Logger.LogError(ex);
throw;
}
var result = new ResultA();
return req.Role == GetRole(req.Id)
}
result.Name = GetName(req.Id);
? new ResponseB(true)
result.Email
= GetEmail(req.Id);
: new ResponseB(false);
MethodB(ReqB
req)
return
result;
{
Logger.Log(“Handling ReqB”);
try
{
return req.Role == GetRole(req.Id)
? new ResponseB(true)
: new ResponseB(false);
Horizontal API
}
catch (Exception ex)
{
Logger.LogError(ex);
throw;
}
}
MethodC(ReqC req)
{
Logger.Log(“Handling ReqC”);
using(var db =
{
return db.
}
Horizontal API
var result = new ResultA();
result.Name = GetName(req.Id);
result.Email = GetEmail(req.Id);
return result;
Logging
Caching
Exception Handling
return req.Role == GetRole(req.Id)
? new ResponseB(true)
: new ResponseB(false);
using(var db =
{
return db.
}
What we don’t like
• WCF services have many
responsibilities; .svc file
makes it hard to
modularize operation
handling
• Generated client code is
clunky and is a
duplication of server-side
contracts; easy to get out
of sync
• Client endpoints scale in
parallel to server
endpoints
Step 1 – Modularizing Operations
• Move to request/response
• Re-imagine each operation’s code as a
separate class – MessageHandler<>
– One-to-One with request
• Provide a hook into WCF internals that will
instantiate and invoke a MessageHandler<>
instead of a service instance (.svc)
• Identify and isolate infrastructural concerns
from MessageHandler<> implementations
Demo
Recap
• Each operation is handled in its own class
– Extensible
– Maintainable
– Testable
.svc File
Invoker
Invoker
Message
Handler
What we don’t like
• WCF services have many
responsibilities; .svc file
makes it hard to
modularize operation
handling
• Generated client code is
clunky and is a
duplication of server-side
contracts; easy to get out
of sync
• Client endpoints scale in
parallel to server
endpoints
Step 2 – Deploy an API
• Goodbye “Add Service Reference”
• Move service definition and data contract
components to a separate assembly
• Package a client wrapper for invoking a service
with the contract assembly
• Open doors to build integration between
products
Demo
Recap
• Contracts moved to separate assembly and
shared with consumers (possibly through
build integration)
• Client API packaged with contracts
– DRY – Single LOC invocation
– KISS – Hide IDisposable from consumer
Shared Contracts
Server.sln
Contracts
Client.sln
(Build)
Contracts
Server Logic
Client Logic
Web Host
Client App
What we don’t like
• WCF services have many
responsibilities; .svc file
makes it hard to
modularize operation
handling
• Generated client code is
clunky and is a
duplication of server-side
contracts; easy to get out
of sync
• Client endpoints scale in
parallel to server
endpoints
Authentication Service
Authentication Client
Financial Service
Financial Client
Search Service
Search Client
Administration Service
Administration Client
Step 3 – Create a single gateway
• Create another service (“Portal”) with a single
operation that will process any request
• Uses the same invoker as all other services to
call a MessageHandler for the request
• Include a client API that will accept any
request
• Add “facilities” under the covers
– Compression
Demo
Recap
Authentication
MH1
MH2
MH3
MH4
Customer
…
SOA
Byte[]
…Request
Portal
Byte[]
N-Tier
DB
Nitpicker Corner
• Async
• Reuse requests for > 1
operations
• Auditing vs. Tracing
• Decorator vs.
IErrorHandler
• .Svc exception smell
• Portal in distributed
environment
• Horizontal APIs enable
discoverability

similar documents