<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Architecture</title>
        <link>http://blogs.sftsrc.com/stuart/category/21.aspx</link>
        <description>Software architecture.</description>
        <language>en-US</language>
        <copyright>Stuart Thompson</copyright>
        <managingEditor>stuart.thompson@sftsrc.com</managingEditor>
        <generator>Subtext Version 1.9.5.0</generator>
        <item>
            <title>Designing for Testability</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2008/07/30/105.aspx</link>
            <description>&lt;p&gt;Automotive manufactures have long been on the vaunted TDD bandwagon.  For years they have harnessed the amazing potential of unit testing, verifying components individually prior to the expensive and time-consuming exercise of assembling them to make a completed vehicle.  Integration testing in the automotive world is very expensive and to find that a single component failure has wasted a fleet of test vehicles as well as many months of construction and fabrication is close to unacceptable.  However, they have also long faced the question of when and where to design for testability; a line still not clearly defined in any industry.&lt;/p&gt;
&lt;p&gt;It makes perfect sense that if a component is to be tested in isolation from the system it will eventually be integrated with that a certain amount of planning is necessary in order to facilitate that testing.  This means that certain designs, while technically and functionally brilliant, may need to be modified if they are ever to be tested.  The question is where to draw the line.  All too often in software engineering the line is drawn firmly on one side or the other, rarely in a position of balance.&lt;/p&gt;
&lt;p&gt;I can understand on a modern motor vehicle with multiple on-board computers performing a variety of related tasks that there is a need to interface with and test those computers thoroughly.  I'm sure that to the component manufacturers the need for extra diagnostic access ports and programmable interfaces is a hindrance to their development; after all they are working in a very closed system.  However, to the test engineers the ability to simulate all manner of failures and receive highly detailed information about everything the computer is doing is absolutely indispensible.  They cannot guarantee the component functions correctly without it.&lt;/p&gt;
&lt;p&gt;Unfortunately this desire for components to be testable can easily get out of hand.  Consider that a test engineer is tasked with ensuring that the onboard computer functions at various speeds.  Unforuntately his equipment is bulky and doesn't fit inside the vehicle.  Even at low speeds he finds that keeping up with a car in motion requires him to run alongside pretty quickly.  Should he require that the car not go faster than 8mph in order to ensure that he can completely guarantee the functionality of the computer for the legal range of speeds he is able to test?  Something tells me that the manufacturer wouldn't be able to sell too many of that particular model.&lt;/p&gt;
&lt;p&gt;Instead the test engineer must find other ways to test the car at high speeds.  Custom models of the car are constructed that allow a connected rig to be tethered to the car, carrying all of the the test equipment alongside even at high speeds.  At even higher speeds, motion simulations and car treadmills are employed to allow for testing that the tethered rig is unsafe for.  The design of the car wasn't limited to a maximum speed of 8mph, rather a compromise was found to allow the right balance of functionality and testing.&lt;/p&gt;
&lt;p&gt;In software engineering, we have a variety of tools and frameworks at our disposal to accomplish similar testing of software.  Unit testing frameworks, mock frameworks, dependency injection containers; they are tools.  Each plays a specific role and solves a particular flavor of problem, however none of them are all-encompassing and all of them require thought before use.&lt;/p&gt;
&lt;p&gt;There is a growing epidemic of code grown out of the desire for "high coverage" unit testing.  However, some of the motivations behind this testing appear to have taken an 8mph turn somewhere; for the worse.  In an effort to improve code quality, the initiatives towards testing have started to build 8mph cars with 6 wheels and no doors.  In terms of test coverage the cars are truly superb, but from the outside many consumers are left scratching their heads and wondering where it all went wrong.&lt;/p&gt;
&lt;p&gt;I usually find that if a particular design decision is inhibiting the testability of a component, one of three things is happening:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The design is so tightly coupled and stable that no testing could hope to penetrate the darkness of the black box surrounding it.  (i.e. a dll with one 5,000 line method inside that does "something")&lt;/li&gt;
&lt;li&gt;The design is so abstract that is doesn't actually do anything.  (i.e. a dll containing only interfaces - test that suckas!)&lt;/li&gt;
&lt;li&gt;The testing tool being applied is the wrong one for the job.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;As a software engineer, I can fix 1 and 2.  Fortunately with good design and architecture we can actually prevent 1 and 2 from ever reaching QA in the first place.&lt;/p&gt;
&lt;p&gt;There isn't much I can do about number 3.  This is where I ask for the line to be moved a little with regards to the tool that is being employed.  Here are a few examples of hammering screws and screwing nails.&lt;/p&gt;
&lt;p&gt;Static methods, unless invoked through reflection, attract coupling from consumers.  That is to say that if an assembly contains a static method, there is a good chance that something calling that static method has a strong reference to the assembly that exposes it.  This is not a bad thing and there are many places where such a design makes perfect sense.  However, in certain situations, this can cause mocking frameworks to perform more work than necessary to set up the premise for a unit test because they can't mock away the reference the exposed assembly that performs work.  This is because mocking frameworks are ideal for mocking abstract implementations and poor for mocking tightly coupled components.  There is nothing to mock because everything is explicitly stated.  See screw, swing hammer.  Static methods are perfect for unit testing thanks to the magic of reflection.  Inspect the method contract (the logical contract not the physical source code - i.e. what, in English, does it do) and based upon that contract construct a suite of tests to affirm that the method is indeed doing what it promised it would.&lt;/p&gt;
&lt;p&gt;Service assemblies, such as configuration loaders or proxies, tend to operate more upon interfaces than implementations.  That is because the value they add is an operation upon some implementation of an interface rather than a concrete process defined up front.  This is the provider model.  We write a set of interfaces describing the kinds of things a provider can do.  We also write a set of services than help those providers achieve some work.  We don't write the actual providers themselves because this is a plugin model.  Well, how do we test a provider that hasn't been written yet?  Wait, this could be hard in unit testing.  We call a method on an interface but have no way to know what the "as yet unwritten" provider will do in that method call and have no way of knowing whether the result is correct.  NTemporalDisplacementUnit 1.0 hasn't been released yet so we can't do it in a state of temporal flux either...panic!  But wait, in thinking about the problem further we realise that we don't care what the provider does.  The contract we are providing is that we will interact with a provider in a predictable and documented fashion.  As long as we interact with the interface in the correct way and at the correct time, our part of the contract is fulfilled.  Woohoo!  That's what a mock framework is for.  We mock up a provider and check that our service correctly interacts with the provider.  Mock frameworks are great for this.  Finally, a nail that we can hit with our hammer.&lt;/p&gt;
&lt;p&gt;If you find that such thinking manifests itself in dogmatic emails that state "static methods shouldn't be used because they inhibit testability" or "interfaces are bad because we can't get coverage with them." then it might be time to inspect both the situation and the tools and see that the two are being correctly paired.&lt;/p&gt;
&lt;p&gt;The goal of testing is to improve the quality of the end product, not to turn lots of lights a pretty shade of green.  8mph cars with lots of green LEDs and no doors for great dogmatic case study's and really awful consumer responses.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/105.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2008/07/30/105.aspx</guid>
            <pubDate>Wed, 30 Jul 2008 19:56:41 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2008/07/30/105.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/105.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day Three - Creating Custom WCF Behaviors</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/17/72.aspx</link>
            <description>&lt;p&gt;
Presenter: Rob Daigneau&lt;br /&gt;
Code: &lt;a href="http://www.designpatternsfor.net"&gt;http://www.designpatternsfor.net&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I think it must either be Rob Daigneau or the topic of Windows Communication Foundation because this was yet again another superb talk.  WCF was of little interest to me when I first arrived at this conference, however now I found myself extremely interested in learning more about how it might improve the architecture of my projects.  It doesn't feel, like so many unfortunately do, like a technological solution in search of a problem.  I can already see where I could apply WCF to bring a robust communication framework into the design of my applications.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Aspect-Oriented Programming&lt;/b&gt;&lt;br /&gt;
Aspects encapsulate the handling of a particular concern.  The aspects can intercept the flow of program execution to inject their code and perform work.  Custom behaviors in WCF borrow a lot of concepts from the aspect-oriented programming field of thought.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Why Custom Behaviors&lt;/b&gt;&lt;br /&gt;
There are several reasons for defining custom behaviors using interception logic:&lt;br /&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Validate parameters and messages&lt;/li&gt;
&lt;li&gt;Alter or Transform parameters and message&lt;/li&gt;
&lt;li&gt;Log information about messages&lt;/li&gt;
&lt;li&gt;Redirect operations to invoke - change the Action that is called based upon some part of the message body&lt;/li&gt;
&lt;li&gt;Custom Error Handling&lt;/li&gt;
&lt;li&gt;Custom Authorization&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;
&lt;b&gt;WCF Behaviors&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;Extensibility&lt;/u&gt;&lt;br /&gt;
The WCF runtime provides hooks for extensibility at the Sevice Model Layer and the Channel Layer.
&lt;br /&gt;&lt;br /&gt;
&lt;u&gt;Service Model Layer&lt;/u&gt;&lt;br /&gt;
Proxy and Dispatcher
&lt;br /&gt;&lt;br /&gt;
&lt;u&gt;Channel Layer&lt;/u&gt;&lt;br /&gt;
Client or Service Side
&lt;br /&gt;&lt;br /&gt;
Behaviors are injected in the Service Model Layer.  Extensions are added in the Channel Layer.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Framework Requirements&lt;/b&gt;&lt;br /&gt;
In order for custom behaviors to function, the .NET framework and WCF will need to be installed on the client because otherwise the .NET specific injection hooks on the client side will not function.
&lt;/p&gt;


&lt;p&gt;
&lt;b&gt;Interceptors&lt;/b&gt;&lt;br /&gt;
Interceptors are a means to extend the WCF runtime.  The System.ServiceModel.Dispatcher contains a number of interfaces that, if implemented, can be used to define custom behaviors.  By intercepting the ServiceHost.Open (on the service side) and ChannelFactory.Open (on the client side), the behaviors can be added to the WCF runtime.  In this way, the flow of program execution will be intercepted at known join-points and the code within your custom behavior classes will be executed.  Interceptors can also be injected at specific points on the dispatcher.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Potential Scenarios&lt;/b&gt;&lt;br /&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;IParameterInspector&lt;/li&gt;
&lt;li&gt;IClientMessageFormatter&lt;/li&gt;
&lt;li&gt;IClientMessageInspector&lt;/li&gt;
&lt;li&gt;IDispatchMessageInspector&lt;/li&gt;
&lt;li&gt;IDispatchOperationsSelector&lt;/li&gt;
&lt;li&gt;IDispatchMessageFormatter&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;
&lt;b&gt;Loading the Behaviors into the WCF Runtime&lt;/b&gt;&lt;br /&gt;
In order to inject behaviors, their exist interfaces in the &lt;span style="font-family:Courier,New"&gt;System.ServiceModel.Description&lt;/span&gt; namespace.
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;IServiceBehavior&lt;/li&gt;
&lt;li&gt;IEndpointBehavior&lt;/li&gt;
&lt;li&gt;IContractBehavior&lt;/li&gt;
&lt;li&gt;IOperationBehavior&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;u&gt;Scoping&lt;/u&gt;&lt;br /&gt;
Each of these is scope within the other, with the IServiceBehavior implementations having the power to inject behaviors on services, endpoints, contracts, and operations.  Each tier down can inject behaviors on a smaller scope than the previous interface implementation, meaning that IOperationBehavior implementations can only inject behaviors on operations.
&lt;br /&gt;&lt;br /&gt;
&lt;u&gt;Means on Injection&lt;/u&gt;&lt;br /&gt;
Behaviors may be injected through configuration, attributes, or programmatic means.  All behaviors can be applied programmatically.  Only certain behaviors can be applied via configuration or through the use of attributes.
&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/72.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/17/72.aspx</guid>
            <pubDate>Thu, 18 Oct 2007 00:10:17 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/17/72.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/72.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day Two - Implementing SOA Design Patterns with WCF</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/17/69.aspx</link>
            <description>&lt;p&gt;Presenter: Rob Daigneau (Chief Architect, SynXis)&lt;br /&gt;
Blog: &lt;a href="http://www.designpatternsfor.net"&gt;http://www.designpatternsfor.net&lt;/a&gt;&lt;br /&gt;
Author of an upcoming book on SOA Design Patterns published by Addison Wesley. &lt;/p&gt;
&lt;p&gt;This was definitely the most interesting talk of the conference so far.  It's pleasing to see an advanced course that really got into some great architectural discussions and provided applicable techniques for solving difficult SOA problems such as maintenance, versioning, forward, and backward compatibility.  This session is geared towards the WCF developer who is looking to improve their service oriented design architecture.   &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;There are two typical types of SOA services:&lt;br /&gt;
&lt;u&gt;Domain Services&lt;/u&gt;&lt;br /&gt;
These are the elemental building blocks upon which everthing else is built. &lt;/p&gt;
&lt;p&gt;&lt;u&gt;Enterprise Services&lt;/u&gt;&lt;br /&gt;
Enterprise services are composities of domain services that are pulled together in order to provide more comprehensive, enterprise-level solutions. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Domain Services&lt;/strong&gt;&lt;br /&gt;
Domain services are designed primarily to address a business problem within a particular domain.  They encapsulate business logic and data management to abstract the details of the service from consumers of that service.  The roles of domain services are also to encapsulate and leverage existing business logic components and classes to allow for re-use of existing components that would be too expensive to re-write.  When encapsulating business logic it is performing the role of a mediator.  When simplifying the interface to re-used or abstracted objects, it is acting in the role of a facade.  A domain service can be thought of as an additional (fourth) layer that exists between the UI and business layers in the application.  This does not mean that every application that wishes to communicate with the business tier needs to go through the service.  The service layer itself can introduce a performance hit as it may be abstracting the fact that the business logic components are executing on a different machine than the caller.  Certain applications may still want to access the business tier directly and this is perfectly acceptable even with an available domain service. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Exchange Patterns&lt;/strong&gt;&lt;br /&gt;
&lt;u&gt;Request-Response Pattern&lt;/u&gt;&lt;br /&gt;
The most basic message exchange pattern is for a request to be issued to the service by the client which then waits for a response from that service.  The disadvantage of this pattern is that the client is sitting in an idle state until a response is received from the service.  There is no guarantee of how long it might take for the service to respond and hence no way to know how long the client will be locked in the waiting state. &lt;/p&gt;
&lt;p&gt;&lt;u&gt;In Only&lt;/u&gt;&lt;br /&gt;
An example of the "In Only" pattern, also known as Fire and Forget, is a service such as a booking system that takes a request for information and then indicates that a response will be delivered once some process has completed.  This might be in the form of an email will be sent to a customer once their original request has been processed.  The disadvantage with this system is that the client has to wait an indeterminate amount of time for a response and has to check for that response periodically, i.e. a user checking their Inbox for a confirmation message.  This pattern does not work well when both client and service and software programs.  Client software polling for a response is a sub-optimal architecture. &lt;/p&gt;
&lt;p&gt;&lt;u&gt;Duplex&lt;/u&gt;&lt;br /&gt;
This message exchange pattern uses asynchronous methods with callbacks to allow a client to continue working after it sends the request.  A callback method is sent as part of the request such that the service can invoke that callback method with a response once the work of the service has been complete.  However, this requires that the client is still alive and hence able to receive the response once the service is ready to make the callback. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Duplex (callback) Pattern in Practice&lt;/strong&gt;&lt;br /&gt;
&lt;u&gt;How callback works from the Client&lt;/u&gt;&lt;br /&gt;
Configuration of the message exchange pattern that will be used can be handled via attributes upon the service definitions.  The channel description for the contract is specified in the ServiceContract attribute on the client.  In this way, the client can issue a message and continue processing, knowing that the callback will be received once the service has completed its work. &lt;/p&gt;
&lt;p&gt;&lt;u&gt;How Callback works from the Service&lt;/u&gt;&lt;br /&gt;
The implementation of the service can use &lt;span style="FONT-FAMILY: Courier,New"&gt;OperationContext.Current.GetCallbackChannel&amp;lt;&amp;gt;&lt;/span&gt; to get a callback channel to the client that issued the request.  This gets a specific callback channel that can be used to callback the client with the response.  This same mechanism can also be used to implement a publisher subscriber pattern by building a registry of subscribers to callback with the response.  In this way, a single request from the &lt;em&gt;Publisher&lt;/em&gt; of information can be called back to multiple &lt;em&gt;Subscribers&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Data Transfer Objects&lt;/strong&gt;&lt;br /&gt;
Very similar in definition to the application objects that we use (&lt;em&gt;you &lt;strong&gt;DO&lt;/strong&gt; use objects that are free from business logic to transfer data right?&lt;/em&gt;), data transfer objects are used in messages sent to and from the service in order to abstract the definition of an object and avoid having parameters listed in any service contract.  This loosens the coupling of the service and client and reduces the service area exposed by the client by reducing all operations involving a particular logical entity to using collections (one item collections for single objects) for all transactions involving a particular entity. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service Message and Contract Amendments&lt;/strong&gt;&lt;br /&gt;
Better even than passing data transfer objects in service operations, consider using a service message object instead.  What is the justification for this?  Consider that some additional metadata needs to be transmitted for a particular operation that does not logically fit within the definition of a particular data transfer object.  This metadata would classically (in an RPC mindset) be appended to the signature of the operations in the service contract.  However, this tightens the coupling and increases the surface area of the service contract.  If the service operation simply took a service message as the single parameter, this message could be extended with the metadata without affecting the contract.  Even better, consider that a message contains a data transfer object specific extension object that will always contain the additional message metadata and can itself be extended over time.  This keeps the definition of the message object itself from changing as new metadata is introduced.  This extension object is known as a collection of &lt;em&gt;contract amendments&lt;/em&gt; as it literally encapsulates the amendments that have been made to the service contract over time.  The amendments property should be declared within the message when it is first developed, despite the fact that it will start it's life as an empty and essentially redundant collection.  This allows for the addition of amendments over time without having to modify the message object at any point in its life.  This is an extremely desirable stability in the only parameter passed to the operations in a service contract.  The final consideration here is that amendment properties must be marked as not required, otherwise existing clients that are unaware of the new amendment will break. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forward and Backward Compatability&lt;/strong&gt;&lt;br /&gt;
The service should check for the presence of the amendment properties, in the case that the properties are null, it can be determined that an older client is accessing the service.  In order to provide appropriate compatability, the service should continue to work even if this extension data is not provided.   &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The MessageContract Attribute&lt;/strong&gt;&lt;br /&gt;
There is little information out there about the &lt;span style="FONT-FAMILY: Courier, New"&gt;MessageContract&lt;/span&gt; attribute for use in classes that define transport-level messages.  It gives much greater control that the oft-touted &lt;span style="FONT-FAMILY: Courier, New"&gt;DataContract&lt;/span&gt; class. &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/69.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/17/69.aspx</guid>
            <pubDate>Thu, 18 Oct 2007 00:02:20 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/17/69.aspx#feedback</comments>
            <slash:comments>84</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/69.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>