Here's a great site I came across that concisely guides through the process.
http://www.codingthearchitecture.com/pages/book/software-architecture-document-guidelines.html
It looks like it based on Software Systems Architecture: Working with Stakeholders Using Viewpoints and Perspectives by Nick Rozanski and Eoin Woods.
Monday, December 19, 2011
Tuesday, November 15, 2011
Justifying Unit Testing & TDD
The cost benefits of Unit Testing is a interesting topic to discuss. Anyone who has experience with it or knowledge of it at least, can easily see over time it will reduce costs and increase quality. However selling it to business people always seems difficult. I often liken it to working in a factory, imagine an senior engineer informs management that with a little investment he has an idea that will significantly reduce costs, time-lines and increase quality. He can't exactly quantify, but has seen it work when he worked for a competitor. Most business people I have worked with, always want a dollar figure or a number of hours saved per year. This is almost impossible to estimate with any accuracy, and you get held to it if things look like they are going wrong.
IEEE did a study about the cost of defects at each phase of the software development lifecycle, attaching the graph they published (CostofCorrectingDefects). An online version is available here.
“Get the test team involved and knowledgeable about the TDD approach. The test team should not accept new development release if the unit tests are failing”
I’d say all software development teams know that unit testing is the most effective way to find bugs. According to IEEE the cost to correct a bug in the coding stage is $977 whereas $7136 in the Testing stage. That is why unit testing which is in the coding stage is so important. For Agile developments this is even more so as the code and design is changing so fast that without unit tests the whole building can collapse and many large scale agile groups see their velocity slow down: Story.
IEEE did a study about the cost of defects at each phase of the software development lifecycle, attaching the graph they published (CostofCorrectingDefects). An online version is available here.
Quote from a study called "Realizing quality improvement through test driven development: results and experiences of four industrial teams". The full article can be found here.
“TDD seems to be applicable in various domains and can significantly reduce the defect density of developed software without significant productivity reduction of the development team. Additionally, since an important aspect of TDD is the creation of test assets—unit, functional, and integration tests. Future releases of these products, as they continue using TDD, will also experience low defect densities due to the use of these test assets”
“Convince the development team to add new tests every time a problem is found, no matter when the problem is found. By doing so, the unit test suites improve during the development and test phases”
There's also a good chapter in Roy Osherove's book "The Art of Unit Testing" (the defacto bible on unit testing). He gives an example of a project he worked on that shows two teams developing similar features with the same sized team and similar skill levels:
Stage | Team without tests | Team with tests |
---|---|---|
Implementation (coding) | 7 days | 14 days |
Integration | 7 days | 2 days |
Testing and bug fixing | Testing 3 days Fixing 3 days Testing 3 days Fixing 2 days Testing 1 day Total: 12 days | Testing 3 days Fixing 1 day Testing 1 day Fixing 1 day Testing 1 day Total: 8 days |
Overall release time | 26 days | 24 days |
Bugs found in production | 71 | 11 |
Here's a similar story of why unit testing helps teams who use it save time and money versus those that don't: http://pathfindersoftware.com/2009/04/unit-testing-can-you-afford-not-to.
I’d say all software development teams know that unit testing is the most effective way to find bugs. According to IEEE the cost to correct a bug in the coding stage is $977 whereas $7136 in the Testing stage. That is why unit testing which is in the coding stage is so important. For Agile developments this is even more so as the code and design is changing so fast that without unit tests the whole building can collapse and many large scale agile groups see their velocity slow down: Story.
Friday, October 21, 2011
My Type Visualiser Project
I've always like to be able to visualise software designs in diagram form. When looking at code its a constant struggle to filter out the detail and only take notice of the important stuff. Most of the time learning a new code base or refactoring code the details are not important immediately. I find just exploring the dependencies of a type and other types it consumes a good place to start understanding a class. Easier said than done.
Visualising a type and its dependencies and relationships to other types, is useful to me for two reasons:
1) Assessing what this subject type is doing, and is it well structured.
2) How difficult would it be to get the subject type under test.
Enter the Type Visualiser.
This tool is intended to target one .NET type and visualise its associations. Different relationships are modelled as different coloured lines and arrow heads. Line thickness indicates how often a type is consumed by the subject or how many different fields or properties use other types. The style is loosely based on UML, but is by no means intended to strictly follow UML.
The tool targets compiled .NET libraries (and executables) and presents a list of types it can find inside the chosen library.
The tool is intended to give a strategic overview of a type and how it relates to other types, so members themselves are not shown. Only statistics and totals are given to provide a sense of how big and complex a type is. Nearly everything has a tooltip to indicate the various symbols and lines.
I'm intending on adding a Testibility Index to indicate how "testable" a type is. The more strong relationships it has (to sealed or concrete classes as opposed to interfaces and abstracts) the higher the index. The more lines of IL code and members the higher the index. I haven't really ironed out the details of how this feature will work yet.
If there's strong interest I might open source the project.
These diagrams help me assess how much time/effort is required to get an existing piece of code under test and refactor it as well as add new features. Obviously the more complex the diagram the more this efforts any estimates I give. For example, this monster class shown below is definitely a huge concern in terms of complexity and the number of strong types is "welded" to.
Clearly, this subject type is broken.
Visualising a type and its dependencies and relationships to other types, is useful to me for two reasons:
1) Assessing what this subject type is doing, and is it well structured.
2) How difficult would it be to get the subject type under test.
Enter the Type Visualiser.
This tool is intended to target one .NET type and visualise its associations. Different relationships are modelled as different coloured lines and arrow heads. Line thickness indicates how often a type is consumed by the subject or how many different fields or properties use other types. The style is loosely based on UML, but is by no means intended to strictly follow UML.
The tool targets compiled .NET libraries (and executables) and presents a list of types it can find inside the chosen library.
The tool is intended to give a strategic overview of a type and how it relates to other types, so members themselves are not shown. Only statistics and totals are given to provide a sense of how big and complex a type is. Nearly everything has a tooltip to indicate the various symbols and lines.
I'm intending on adding a Testibility Index to indicate how "testable" a type is. The more strong relationships it has (to sealed or concrete classes as opposed to interfaces and abstracts) the higher the index. The more lines of IL code and members the higher the index. I haven't really ironed out the details of how this feature will work yet.
If there's strong interest I might open source the project.
These diagrams help me assess how much time/effort is required to get an existing piece of code under test and refactor it as well as add new features. Obviously the more complex the diagram the more this efforts any estimates I give. For example, this monster class shown below is definitely a huge concern in terms of complexity and the number of strong types is "welded" to.
Clearly, this subject type is broken.
Wednesday, October 5, 2011
Some Resources on Patterns of Data Access with EF
Ayende's thoughts on Repository Pattern.
(I'm not convinced by this article. It talks about separation from Data Access but it doesn't look unit testable to me. Check out the fields on the BLL class Repository, how would you mock/stub that?)
This definitely more interesting than the above article, but I still can see how the Intelligent Query Pattern gives much cleaner separation of concerns. Although, I'm only about 90% there. There's still a case (in my mind at least) to still allow simple linq queries direct against EF.
A long read, but some complimentary points on EF and good insights into NHibernate.
An tiny lightweight alternative to EF PetaPoco (although it appears it relies on SQL strings - yuck).
Tuesday, October 4, 2011
Serialising a Linq Query to Json
IEnumerable<Employee> empJson = from emp in employees where emp.Department == "IT Department" select emp; var ser = new DataContractJsonSerializer(typeof(IEnumerable<Employee>)); using (stream = new MemoryStream()) { ser.WriteObject(stream, empJson); string json = Encoding.Default.GetString(stream.ToArray()); return json;
}
Friday, September 23, 2011
Resharper's Type Member Layout
I've just started using the Type Member Layout feature in Resharper, it wasn't new in Resharper 6, but I haven'd noticed it util recently. I've found Regionerate a handy tool to ensure that members in a class are sorted in a predictable order that isn't open to interpretation like sorting by flow or logical grouping. I've never been a fan of regions for that same reason, what to put in a region is largely a matter of opinion, and can make code less discoverable. But, my biggest bugbear with Regionerate is the double spacing it leaves between members despite countless hours fiddling with its config xml.
Resharper's Type Member Layout is, well, sharper.
Resharper's Type Member Layout is, well, sharper.
I spent some time finding and fine tuning a 100% StyleCop compliant format here's the xml configuration for it.
Wednesday, August 31, 2011
Handy Debugging Attributes
http://msdn.microsoft.com/en-us/library/ms228992.aspx
[DebuggerDisplay("Count = {count}")] class MyHashtable { public int count = 4; }
[DebuggerBrowsable(DebuggerBrowsableState.Never)] public static string y = "Test String";[DebuggerTypeProxy(typeof(HashtableDebugView))] class MyHashtable : Hashtable { private const string TestString = "This should not appear in the debug window."; internal class HashtableDebugView { private Hashtable hashtable; public const string TestStringProxy = "This should appear in the debug window."; // The constructor for the type proxy class must have a // constructor that takes the target type as a parameter. public HashtableDebugView(Hashtable hashtable) { this.hashtable = hashtable; } } }
Saturday, August 13, 2011
Effective Strategies for Breaking Dependencies
I've just finished reading Michael Feathers' book Working Effectively with Legacy Code and I highly recommend it. Despite most of it is targeting C++ and Java, there are a small number of code examples in C#, the principles most definitely still apply. This book is a must have for anyone serious about improving an existing code base without an expensive rewrite.
The code change workflow:
Adapt Parameter
Break Out Method Object
Encapsulate Global References
Expose Static Method
Extract and Override Call
Extract and Override Factory Method
Extract and Override Getter
Extract Interface
Introduce Instance Delegator
Introduce Static Setter
Parameterise Constructor
Parameterise Method
Primitivise Parameter
Pull Up Feature
Push Down Dependency
Replace Global Reference with Getter
Subclass and Override Method
Replace Dependency with a Delegate
The biggest take-away for me was the list of strategies for breaking dependencies. This post is intended to be a quick reference index for the book. Are you working with legacy code that is not clean and tidy? You Need This Book.
The code change workflow:
- Plan the change, know what methods you need to alter.
- Understand the structure of the types and methods, diagram if necessary.
- Get the methods you want to change under test (see below for breaking dependencies). Only make the absolute minimum changes to get methods under test when no tests exist. Don't succumb to the temptation of changing too much. Basics only, break good design patterns if necessary; get the methods under test then fix the design breaks.
- If possible program with a partner, and they should be constantly asking "what are you doing now? One thing at a time, pick one. Are you sure we need that to get the method under test?" Change chairs every 20-30 minutes.
- Make the original intended change.
Page 326. Use this when you can't extract a full interface or its impractical to do so. This works when the usage of the method parameter only accesses a small number of members on the parameter. Ideally the return types of the members used on the parameters must be simple or mockable types.
public void Foo(HttpWebRequest request) {
...
var type = request.ContentType;
...
}
becomes
public void Foo(string contentType)
{
...
}
or
public void Foo(IRequestMetaData requestData)
{
...
var type = requestData.ContentType;
...
}
Break Out Method Object
Page 330. Useful when the method you want to change is very large, or the work required to get the whole method under test is significant. Also consider Expose Static Method. The idea is to move the entire method to a new class and the parameters of the method become instance fields, and properties and/or constructor arguments. Once in its own class it should be easier to break dependencies using the other techniques.
Encapsulate Global References
Page 339. This is used to break dependencies on static / global references. Essentially you extract the global data encapsulate it in an interfaced (or overridable) class. It might be appropriate to Expose a Static Setter or access the new encapsulated class via a singleton IoC container.
Expose Static Method
Page 345. Use this when a method you are trying to get into test doesn't access any instance members. Useful when the class itself has many dependencies. Making the method static means you can concentrate on the method and not the other dependencies in the class. Resharper will suggest making a method static by default.
Extract and Override Call
Page 348. This is useful when a target method depends on another within the same class which you are not really concerned with right now. Remove the dependencies on the other method by creating a test class and inheriting from the class and overriding the method you are not concerned with. This way you can call the original method and your overriden method can return dummy data and skip other dependencies.
[Edit - also see comments below. Another option would of course be to use an IoC container to avoid using virtual method calls in the constructor. However sometimes introducing an IoC container into legacy code can be time consuming; although it is preferential when possible.]
[Edit - also see comments below. Another option would of course be to use an IoC container to avoid using virtual method calls in the constructor. However sometimes introducing an IoC container into legacy code can be time consuming; although it is preferential when possible.]
Extract and Override Factory Method
Page 350. When a class you need to change creates other dependencies in the constructor it can be useful to extract those creation lines of code elsewhere. Move all the code that creates other types into a new virtual method and call it from the constructor. A test class can be used to then override the new virtual factory method to return mock dependencies.
Extract and Override Getter
Page 352. This is again concerned with creation of dependencies in the constructor or field initialisers. Sometimes a constructor can contain a large number of arguments or the class accesses a high number of singletons. Also when the constructor creates types sometimes using Extract and Override Factory Method isn't practical if it means creating many factory methods. This technique creates properties that return the types, the properties refer to private fields and are initialised to null. All code within the class is refactored to use the properties. On first access the property initialises the field and returns the field thereafter. Under test private accessors (MsTest) or reflection can be used to set the field.
Extract Interface
Page 362. I see this as the primary tool for breaking dependencies. The idea is to take a dependency of a class and create an interface that matches its public API. Ideally you control the source of the dependency class and you implement the new interface with that class. (If you don't read the chapter on "My Application is All API calls" Chapter 15). The next step is to refactor the code you are looking at changing to use the new interface.
Introduce Instance Delegator
Page 369. This is another technique for working with Static classes. The idea is to have an instance method that delegates to the static method. All dependent code uses the instance methods NOT the static methods. (Changes can be piece-meal, only change code that your are trying to get under test right now). Now a testing subclass (mock) can be created overriding the behaviour.
Introduce Static Setter
Page 372. Although mutable static data should be avoided working with it is almost inevitable. Use this strategy when you have static global data you need to set or change the behaviour under test. The idea is to have a setter that you use to swap out static data under test. Fortunately in C# you can use a private accessor to set a private property or field and avoid having a public setter that could be misused. Another way is to use an internal setter and use the InternalsVisibleToAttribute.
Parameterise Constructor
Page 379. This is another way to remove code from a constructor that instantiates other classes. Simply create constructor parameters for any class created in the constructor and make the calling class instantiate it and pass it in.
Parameterise Method
Page 383. This is very similar to Parameterize Constructor, although there is good reasons to not create classes in constructors there's no broad rule to not do this in methods, because that would be kind of pointless. The idea is to pass in any difficult to create dependencies in as parameters. This is a bit of a cop out, as it just pushes the problem into another class that you might need to write tests for tomorrow. First try Extract Interface and use DI, or Extract Factory Method, or Extract and Override Call.
Primitivise Parameter
Page 385. This is a really simple handy thing to try first when working with difficult method parameters. Resharper has really good support for this. The idea is to find the simplest base class for a parameter and use that instead. Quite often there is an existing interface or abstract class that allows the method to still function and is easier to mock.
Pull Up Feature
Page 388. If you are prevented from getting a class under test because some unrelated methods in it have difficult and also unrelated dependencies, you might be able to use this technique. Create an abstract base class pull your affected methods into the base class, and work through compile errors until it compiles. You might also need to use Extract Interface or other techniques as well. Then you can create a testing subclass that tests only the affected methods.
Push Down Dependency
Page 392. When Subclass and Override Method is problematic because there are too many dependencies, this is another option. You might be able to make the current class abstract and push the difficult dependencies down into a subclass. You may need to use this in conjunction with Extract Interface for the dependencies or you might be able to wrap them into functional calls rather than using the dependency directly. After you're done with this refactoring you will be able to create a testing subclass to test your affected methods.
Replace Global Reference with Getter
Page 399. This is another technique for working around global data. This technique only really works in C# if the global data is not static (ie returned from a static or global container). This technique requires you to replace all public fields or properties on the global instance with virtual property getters. This allows you to subclass the global with a fake under test. I personally find this a bit awkward and would rather use Extract Interface and maybe a IoC container, or introduce a Static Setter.
Subclass and Override Method
Page 401. This is a core technique for focusing on the methods you care about using inheritance to override the ones you don't. Create a subclass of the subject class and override methods you don't care about that are called from the one you are trying to get under test. You will need to make the members affected virtual and unseal the class if necessary. This is a good starting out technique when working on a class that has never been unit tested before.
Replace Dependency with a Delegate
Page 396 - this is an adaptation of Replace Function with Function Pointer. Sometimes it might be simpler than using Extract Interface or other techniques which can require a bit of work. The idea is to pass in a delegate instead of the difficult dependency itself. This only works if the usage of the dependency involves simple or already testable return types.
public void Write(Stream stream) {
...
stream.Write(bytes);
}
becomes
public void Write(Action<byte[]> writer) {
...
writer(bytes);
}
Lazyload Dependency Property Getters
This is something I do frequently to avoid creating or getting dependencies in the constructor. Its essentially an adaptation of Extract Factory Method. The idea is to use properties within a class to access all external dependencies. By default on first access the dependency will return the production default class, but using a private accessor you can inject a fake in test.
public void Write(Stream stream) {
...
stream.Write(bytes);
}
becomes
public void Write(Action<byte[]> writer) {
...
writer(bytes);
}
Lazyload Dependency Property Getters
This is something I do frequently to avoid creating or getting dependencies in the constructor. Its essentially an adaptation of Extract Factory Method. The idea is to use properties within a class to access all external dependencies. By default on first access the dependency will return the production default class, but using a private accessor you can inject a fake in test.
public Wheel TheWheel {
get {
return this.backingField ?? (this.backingField = new ProductionWheel());
}
}
get {
return this.backingField ?? (this.backingField = new ProductionWheel());
}
}
// TODO: Code examples
Friday, August 12, 2011
Thursday, August 4, 2011
SOA Tenets
I spent some time over the last few days revisiting the tenets of SOA.
1. Boundaries are Explicit
2. Services are Autonomous
3. Services share schema and contract, not class
4. Service compatibility is determined based on policy
Richard Turner, in 2005 the Product Manager for Indigo described the SOA tenets as:
Resources:
http://pradeepgururani.blogspot.com/2005/08/tenets-of-soa.html
http://pradeepgururani.blogspot.com/2005/08/little-about-soa.html
1. Boundaries are Explicit
2. Services are Autonomous
3. Services share schema and contract, not class
4. Service compatibility is determined based on policy
Richard Turner, in 2005 the Product Manager for Indigo described the SOA tenets as:
- Services have explicit boundaries, The only way to interact with a service or to obtain information or modify the state of the service is via its exposed edge. It shouldn't take a string return a string or a opaque bucket of something where you "just have to know whats in there". The service boundary describes explicitly what messages it can receive and what responses it will return.
- Services are autonomous. If I was to build an application that consumed a service outside of my boundary of control then I should not assume the service at the other end implements its functionality in any particular way. I wouldn't be able to influence it to implement one way or another. I won't be able to connect my SQL Server database to directly to their SQL Server database inside the remote service. I'm simply talking to that service through its boundary and it also automatically enforces an isolation layer between our two services. This allows us them to construct very flexible, very de-coupled applications. (The service should not impose on the client any special components to be installed. Nor should it have unrealistic small operations that requires special knowledge to or an invocation sequence).
- Services share schema and contract, not class. More accurately maybe, it does not share objects. Services are about passing information back and forth between two systems such that those entities can communicate in a common fashion. This is not about remoting an object that actually runs on a service remote from me and controlling it from my environment because the other service maybe running on a platform completely different to mine and I may not have knowledge as to how to affect that component and how it runs in that environment. So services are all about passing information back and forth passed "by value" if you will, rather than "by reference".
- Services interoperate based on policy. And the policy can be information such as, for example, as a service if you want to speak to me you must support some kind of security mechanism. Or you must support TCP as a transport protocol. Or that you must support transactions, for example. (You must comply with security to use this service, or you must use TCP or have a client certificate). Policy describes "how" to send the data (with encryption, with authentication requirements, with duplex or one-way messages).
Resources:
http://pradeepgururani.blogspot.com/2005/08/tenets-of-soa.html
http://pradeepgururani.blogspot.com/2005/08/little-about-soa.html
Tuesday, August 2, 2011
SOA Resources 2
Further to my previous resources list.
Thomas Erl's book on SOA Architecture seems to be the industry recognised "go to" resource.
http://www.amazon.com/Design-Patterns-Prentice-Service-Oriented-Computing/dp/0136135161/
Also check out http://www.soapatterns.org/. This is a community site for SOA design patterns.
Thomas Erl's book on SOA Architecture seems to be the industry recognised "go to" resource.
http://www.amazon.com/Design-Patterns-Prentice-Service-Oriented-Computing/dp/0136135161/
Also check out http://www.soapatterns.org/. This is a community site for SOA design patterns.
Thursday, July 28, 2011
Why do I have to clean up Google's data corruption problems?
Today logging into my blogger and gmail account I see I am told there is a problem with my account. In fact, Google has somehow managed to create duplicate accounts for me.
I've been using Google products and Apps since 2004, during this whole time I've always used the same email address that belongs to my domain. So, somehow along the way Google's software has created duplicate accounts for me, one for Apps and one "personal" account. Its ok, though, Google has created a wizard to transfer the data across. But unfortunately, the Google products I'm using are not supported by the tool. Fantastic. It gets better. Its only suggestion from here is to manually move my data from one place to another. Thanks Google.
There is another alternative, create a NEW gmail account and move my "personal" products to a new gmail account. What the hell?! Why? I don't want two accounts. I don't care about your internal politics, I just want to log in with my one and only email address and use my blog, gmail, or anything else.
That said there is no choice, I have to create a new personal gmail account. Done. Now, blogger won't allow me to log in with my primary email address, only the gmail one. HOW THE HELL IS THIS BETTER FOR ME!
Time to look into Office 365.
I've been using Google products and Apps since 2004, during this whole time I've always used the same email address that belongs to my domain. So, somehow along the way Google's software has created duplicate accounts for me, one for Apps and one "personal" account. Its ok, though, Google has created a wizard to transfer the data across. But unfortunately, the Google products I'm using are not supported by the tool. Fantastic. It gets better. Its only suggestion from here is to manually move my data from one place to another. Thanks Google.
There is another alternative, create a NEW gmail account and move my "personal" products to a new gmail account. What the hell?! Why? I don't want two accounts. I don't care about your internal politics, I just want to log in with my one and only email address and use my blog, gmail, or anything else.
That said there is no choice, I have to create a new personal gmail account. Done. Now, blogger won't allow me to log in with my primary email address, only the gmail one. HOW THE HELL IS THIS BETTER FOR ME!
Time to look into Office 365.
Saturday, July 23, 2011
Unity Snippets
MSDN Article Introducing Unity
http://msdn.microsoft.com/en-us/library/cc816062.aspx
Policy Injection and Interception with Unity (Ent Lib 5 April 2010)
http://msdn.microsoft.com/en-us/library/ff660891(v=PandP.20).aspx
MSDN Article April 2011 Policy Injection with Unity
http://msdn.microsoft.com/en-us/magazine/gg598927.aspx
Usage scenarios for Interception and limitations and trade-offs
http://msdn.microsoft.com/en-us/library/ff660890(v=PandP.20).aspx
http://msdn.microsoft.com/en-us/library/cc816062.aspx
Policy Injection and Interception with Unity (Ent Lib 5 April 2010)
http://msdn.microsoft.com/en-us/library/ff660891(v=PandP.20).aspx
MSDN Article April 2011 Policy Injection with Unity
http://msdn.microsoft.com/en-us/magazine/gg598927.aspx
Usage scenarios for Interception and limitations and trade-offs
http://msdn.microsoft.com/en-us/library/ff660890(v=PandP.20).aspx
A good article on domain driven design (DDD)
I read a good article on DDD the other day, and its worth keeping a reference to it.
http://msdn.microsoft.com/es-es/architecture/en
http://msdn.microsoft.com/es-es/architecture/en
Thursday, July 14, 2011
Legacy Test Driven Development Checklist
I'm currently reading Michael Feathers book: Working Effectively With Legacy Code, and I highly recommend it. In the chapter on TDD and he gave, what I think is a great check list.
0) Yes that's right, step zero. Get the class under test.
1) Write a failing test.
2) Get it to compile.
3) Make it pass.
4) Remove duplication.
5) Repeat.
If managers are asking for estimates be sure to include time for step zero. Easier said than done I know, but you have to sell them on the concept of investing in preventative maintenance. Changing the oil and tuning your car doesn't help you get from A to B, but it will make it cheaper in the long run.
Work With Legacy Code by Michael C Feathers
0) Yes that's right, step zero. Get the class under test.
1) Write a failing test.
2) Get it to compile.
3) Make it pass.
4) Remove duplication.
5) Repeat.
If managers are asking for estimates be sure to include time for step zero. Easier said than done I know, but you have to sell them on the concept of investing in preventative maintenance. Changing the oil and tuning your car doesn't help you get from A to B, but it will make it cheaper in the long run.
Work With Legacy Code by Michael C Feathers
Thursday, June 30, 2011
WCF Service Routing Resources
Service routing is used to expose an end-point to consumers that appears as though it is the real service, but actually is routing requests elsewhere. Reasons to do this include: version based routing (older versions go to a different service), or application level load balancing, or protocol bridging, or dynamic message content based routing etc.
Here are some resources in relation to WCF Service routing:
Here are some resources in relation to WCF Service routing:
- MSDN Routing Feature Overview
- Building a Service Router Part 1 - MSDN Magazine (Michelle Leroux Bustamante)
- Building a Service Router Part 2 - MSDN Magazine (Michelle Leroux Bustamante)
Wednesday, June 29, 2011
WCF Network Load Balancing Resources
Useful Pages I have found while researching this topic:
There seems to be three options:
- MSDN on Network Load Balancing WCF
Getting started with load balancing, information for basic Http, Dual Http, and Net Tcp bindings. This is targeting how using external NLB software / hardware appliances affect your WCF configuration and design. - Kenny Wolf on WCF with NLB
Some interesting information and comments on WCF TCP behaviour under NLB. - Any Technology Blog on Load Balancing WCF
Diagramatic overview.
There seems to be three options:
- Utilise external hardware or software NLB'ers. (This is noted by Microsoft as the best practise approach).
- Manually partition your clients so that they hard wired to point to one of service instances. This approach doesn't give good balance but its straight forward in some simple instances.
- Hand craft discovery and balancing code inside your application. This gives the widest fail over options and balancing flexibility. The significant downsides are the workload to develop, and runtime hosting training and maintenance.
Tuesday, June 28, 2011
WCF Extensibility Resources
A great article in a old MSDN magazine explaining the most common extensibility points in WCF.
Extending WCF with custom behaviors
Overview:
There are essentially 5 common points of extensibility in a WCF service (and the corresponding interface to use):
Ensure any implementation of these interfaces also inherits Attribute to allow direct decoration of a contract/operation within code.
Wiring is best done with config or attribute use:
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
<consoleMessageTracing/>
</behavior>
</serviceBehaviors>
</behaviors>
[ServiceContract]
public interface IZipCodeService
{
[ZipCodeCaching]
[ZipCodeValidation] [OperationContract]
string Lookup(string zipcode);
}
Extending WCF with custom behaviors
Overview:
There are essentially 5 common points of extensibility in a WCF service (and the corresponding interface to use):
- Message inspection (IDispatchMessageInspector)
- Operation selector (IDispatchOperationSelector)
- Message formatter (deserialisation) (IDispatchMessageFormatter)
- Parameter Inspection (IParameterInspector)
- Operation Invoker (IOperationInvoker)
Ensure any implementation of these interfaces also inherits Attribute to allow direct decoration of a contract/operation within code.
Wiring is best done with config or attribute use:
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
<consoleMessageTracing/>
</behavior>
</serviceBehaviors>
</behaviors>
[ServiceContract]
public interface IZipCodeService
{
[ZipCodeCaching]
[ZipCodeValidation] [OperationContract]
string Lookup(string zipcode);
}
Friday, June 24, 2011
Windows Process Activation Services (WAS) Reference Resources
WAS is a new process activation model for IIS7. It enables you to host any WCF service using other non-HTTP protocols using IIS's robust and reliable model.
This diagram from MSDN helps to shows the different components and their boundaries:
This diagram from MSDN helps to shows the different components and their boundaries:
- MSDN Magazine article Sep 2007 Extend your WCF services beyong HTTP
- How to host a WCF Service in WAS (.NET4)
- Building a WCF Workflow service and hosting in AppFabric
- Is there a difference between WAS and AppFabric? They appear to be used interchangeably. (Yes, AppFabric extends WAS, IIS hosts, AppFabric provides superior management and monitoring) - StackOverflow.
- Introducing Windows Server AppFabric (what is it, what does it do, and tools it includes)
- A tale of two services - Stef Sewell. (A demo showing differences between standard WCF and Workflow WCF and hosting in IIS).
- Deployment using Powershell - Stef Sewell
Monday, June 20, 2011
AppFabric Cache Resources
AppFabric Cache is a caching mechanism formerly known as Velocity that has been merged into Windows Server. There is also a Azure flavour of it as well, but this resource list focuses on Windows Server.
Monday, June 13, 2011
XML Validation
Its worth documenting this somewhere even though its pretty straight forward.
namespace XmlValidator { using System; using System.IO; using System.Linq; using System.Xml; using System.Xml.Linq; using System.Xml.Schema; public class EasyXmlValidator { private Action<string> output; public EasyXmlValidator(Action<string> outputWriter) { this.output = outputWriter; } public bool Verify(string[] schemaFilenames, string xml) { var schemaSet = new XmlSchemaSet(); foreach (string schema in schemaFilenames) { string content = File.ReadAllText(schema); XDocument document = XDocument.Parse(content); var namespaceElement = document.Root.Attributes("targetNamespace").FirstOrDefault(); var name = namespaceElement == null ? string.Empty : namespaceElement.Value; schemaSet.Add(name, XmlReader.Create(new StringReader(content))); } XDocument doc1 = XDocument.Parse(xml); Console.WriteLine("Validating doc1"); bool errors = false; doc1.Validate(schemaSet, (o, e) => { this.output(string.Format("{0}", e.Message)); errors = true; }); this.output(string.Format("doc1 {0}", errors ? "did not validate" : "validated")); return !errors; } public bool Verify(string schema, string xml) { return Verify(new[] { schema }, xml); } } }
Tuesday, June 7, 2011
DTOs vs Unified Object Models
Great blog post on Info Q discussing differing opinions on the Data Transfer Object pattern and unified object models (used for ORM, business logic, as wire transfer objects, and as Models in Model-View-Controller pattern).
http://www.infoq.com/news/2011/06/DTOs-vs-Objects
In regard to unified models, I have always felt this was forcing to many concerns on a class. In my opinion at least it breaks the single responsibility principle.
http://www.infoq.com/news/2011/06/DTOs-vs-Objects
In regard to unified models, I have always felt this was forcing to many concerns on a class. In my opinion at least it breaks the single responsibility principle.
Friday, June 3, 2011
Wcf Wsdl Generation and Including Schemas
For some reason, when you browse to the WSDL for a ServiceContract you do not get included Schema in the WSDL Types.
For example: Here's a basic demo Wcf Service.
Notice the link to view the actual WSDL file for this service.
This is what the WSDL file looks like :
Notice how the <wsdl:Types /> element is empty. Ideally a WSDL document should be the one stop shop for describing the service.
To view the schemas of the data contracts and other types used by the service you need to add other parameters to the URL as follows:
Xsd0 shows the service actions, the methods and their parameters.
Xsd1 shows the standard scalar types used, ie strings, arrays etc.
Xsd2 shows the custom data contract types defined and used in the service.
Xsd3 (not shown above) will show any enumeration definitions that you have included in operation contracts.
All these schemas can be copied into the <wsdl:types /> element or imported into the element as follows:
<wsdl:types>
For example: Here's a basic demo Wcf Service.
Notice the link to view the actual WSDL file for this service.
This is what the WSDL file looks like :
Notice how the <wsdl:Types /> element is empty. Ideally a WSDL document should be the one stop shop for describing the service.
To view the schemas of the data contracts and other types used by the service you need to add other parameters to the URL as follows:
Xsd0 shows the service actions, the methods and their parameters.
Xsd1 shows the standard scalar types used, ie strings, arrays etc.
Xsd2 shows the custom data contract types defined and used in the service.
Xsd3 (not shown above) will show any enumeration definitions that you have included in operation contracts.
All these schemas can be copied into the <wsdl:types /> element or imported into the element as follows:
<wsdl:types>
<xsd:schema targetNamespace="http://wcf.rees.biz/CalculatorDemo/2011/06/Imports">
<xsd:import schemaLocation="http://localhost:55401/CalculatorService.svc?xsd=xsd0" namespace="http://wcf.rees.biz/CalculatorDemo/2011/06" />
<xsd:import schemaLocation="http://localhost:55401/CalculatorService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="http://localhost:55401/CalculatorService.svc?xsd=xsd2" namespace="http://wcf.rees.biz/CalculatorDemo/2011/06/" />
</xsd:schema>
</wsdl:types>
As an alternative to using a browser to explore the WSDL for a service you can use the SVCUTIL to extract the WSDL and XSD and save them locally.
SVCUTIL /t:metadata http://url_to_service_here.
This will extract the WSDL and all related XSD files onto your local disk in the current folder.
As a courtesy to any third party you are engaging with and co-developing a service always ensure you give them schema's in the WSDL.
Wednesday, May 25, 2011
WCF Known Types and a Generic Resolver
When using abstract types and in Operation Contracts you must use the KnownTypes attribute (or equivalent web.config syntax) to declare to WCF which what subclasses of the given abstract type are allowed to be used. This works ok, but forces you to declare up front what types can be used and if someone adds a new type they must add a KnownTypes attribute for it otherwise WCF will throw exceptions when it is used over a service call. This method is a little awkward, and it also violates the Open Closed principal.
Juval Lowry discusses a better more maintainable approach:
Known Types and The Generic Resolver MSDN Magazine February 2011
Juval Lowry discusses a better more maintainable approach:
Known Types and The Generic Resolver MSDN Magazine February 2011
Tuesday, May 24, 2011
WCF Service Diagnostics Part 1
Sometimes its useful to be able to examine the raw soap messages coming into and out of a service. Especially when trying to interface into a third party service or client. Quite often all you get is WSDL and not much else.
Back in the days of ASMX Web Services you had to write your own SoapExtension to be able get access to the SOAP/XML. Including all the tedious IO mechanics of writing the log information to an external source. WCF has a built in logging mechanism that just needs to be turned on. In addition WCF also has its own log viewer.
Enabling WCF Logging
This requires a few modifications to your web.config. Alternatively you can use the WCF Service Configuration Editor tool from Visual Studio's Tools menu (or located on your disk at: <Program Files (x86)>\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools)
Microsoft Service Trace Viewer
To view a log file double-clicking the file will open it if you leave the extension as *.svclog, The viewer is installed as part of Visual Studio 2010 and will be located on your disk <Program Files (x86)>\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools).
Recommended Settings for Production and Development Debugging etc are recommended by Microsoft here:
http://msdn.microsoft.com/en-us/library/aa702726.aspx
WCF Test Client
Located at <Program Files (x86)>\Microsoft Visual Studio 10.0\Common7\IDE) and is installed as part of Visual Studio. This is a great simple utility for quickly testing services of any kind. In fact it will auto start when using the Visual Studio WCF Application project template.
Its great for quick testing of services and viewing request and response xml.
Packet Sniffing
http://www.pocketsoap.com/tcptrace/
This is useful for sniffing packets at a lower level particularly when you are writing a client that is interfacing into a third party non-Http service.
For Http services it will probably be easier using Fiddler.
Back in the days of ASMX Web Services you had to write your own SoapExtension to be able get access to the SOAP/XML. Including all the tedious IO mechanics of writing the log information to an external source. WCF has a built in logging mechanism that just needs to be turned on. In addition WCF also has its own log viewer.
Enabling WCF Logging
This requires a few modifications to your web.config. Alternatively you can use the WCF Service Configuration Editor tool from Visual Studio's Tools menu (or located on your disk at: <Program Files (x86)>\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools)
<?xml version="1.0"?> <configuration> <system.diagnostics> <sources> <source name="System.ServiceModel.MessageLogging" switchValue="Off,ActivityTracing"> <listeners> <add type="System.Diagnostics.DefaultTraceListener" name="Default"> <filter type="" /> </add> <add name="ServiceModelMessageLoggingListener"> <filter type="" /> </add> </listeners> </source> </sources> <sharedListeners> <add initializeData="C:\web_messages.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp"> <filter type="" /> </add> </sharedListeners> <trace autoflush="true" /> </system.diagnostics> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <diagnostics> <messageLogging logEntireMessage="true" logMalformedMessages="false" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" /> </diagnostics>
...
Microsoft Service Trace Viewer
To view a log file double-clicking the file will open it if you leave the extension as *.svclog, The viewer is installed as part of Visual Studio 2010 and will be located on your disk <Program Files (x86)>\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools).
The complete soap message envelope is shown inside the application data element. On the left pane use the messages tab to show only messages and look for the items that have a named action. This is the action name used in the OperationContract attributes. Or if left blank it will be as shown above using the TempUri namespace.
Recommended Settings for Production and Development Debugging etc are recommended by Microsoft here:
http://msdn.microsoft.com/en-us/library/aa702726.aspx
WCF Test Client
Located at <Program Files (x86)>\Microsoft Visual Studio 10.0\Common7\IDE) and is installed as part of Visual Studio. This is a great simple utility for quickly testing services of any kind. In fact it will auto start when using the Visual Studio WCF Application project template.
Its great for quick testing of services and viewing request and response xml.
Packet Sniffing
http://www.pocketsoap.com/tcptrace/
This is useful for sniffing packets at a lower level particularly when you are writing a client that is interfacing into a third party non-Http service.
For Http services it will probably be easier using Fiddler.
References:
Saturday, May 7, 2011
Memory Leak Diagnostics
More often than not the occurance of memory leaks seem to be related to bad coding practises and sloppy style. (For example not fastidiously unsubscribing to events when you're finished with them). Prevention is always better than an ambulance at the bottom of a cliff for sure. Obviously though, no one is perfect and mistakes will be made, get through peer review and be checked in.
It is surprising though how good the GC actually is, I'm certain that there is loads of sloppy code checked in all the time and more often than not the GC does a better than fair job cleaning up. Isn't managed code grand, allowing us to spend more time writing product. ;-) Sometimes though, it is going to be unable to detect an object or graph of objects are no longer needed.
When this happens you need to be able to profile what is going on a great detail inside memory and the GC.
SOS.DLL is an assmebly provided by the .NET framework for this purpose exactly. Check out this article on Code Project to find out how to use it.
http://www.codeproject.com/KB/ dotnet/Memory_Leak_Detection. aspx
Thanks Marjorie.
It is surprising though how good the GC actually is, I'm certain that there is loads of sloppy code checked in all the time and more often than not the GC does a better than fair job cleaning up. Isn't managed code grand, allowing us to spend more time writing product. ;-) Sometimes though, it is going to be unable to detect an object or graph of objects are no longer needed.
When this happens you need to be able to profile what is going on a great detail inside memory and the GC.
SOS.DLL is an assmebly provided by the .NET framework for this purpose exactly. Check out this article on Code Project to find out how to use it.
http://www.codeproject.com/KB/
Thanks Marjorie.
WCF Asynchronous Services
During a design session the other day someone was asking what are the possibilities for asynchronous calls in WCF. There are are number of ways to do it, each with different attributes.
- When referencing a standard WCF service from the client using the advanced options (of the Visual Studio add service reference dialog) you can generate BeginInvoke and EndInvoke methods. This allows for an "IAsyncResult invocation pattern" (check out MSDN - Invoking synchronous methods asynchronously and good article on Code Project explaining asynchronous calls). Essentially you pass in a call-back that will be called when the method returns, and they you are able to retrieve the method result from the IAsynResult argument provided. This gives a clientside WCF service consuming developer the option to execute standard synchronous WCF services asynchronously. Great if you do not have control over the service. Also ideal if the expected delay between request and response is not larger than 60 seconds or so.
- A standard WCF service can be decorated with IsOneWay=true in the OperationContract attribute. This effectively tells WCF to immediately return the thread back to the caller. No return values or response is possible from such a service, including exceptions. These are fire and forget style services (sometimes called Document Services).
- The most advanced and flexible way is using Callback Contracts. This requires another Contract be defined and specified with the requesting ServiceContract. Also known as Duplex services. Usually the Operations are also decorated IsOneWay=True, indicating that the calling thread is released back to the client immediately. These are ideal when writing a publish/subscribe pattern and the response will be sent back to the client at some future point at an unknown time. It could be minutes or hours, or it could generate 100 responses over time for one "subscribe" request. Its almost like an event subscription. See the MSDN article referenced below for more info.
*EDIT* I would recommend avoiding using this pattern if possible, a far more robust way of achieving the same results without resorting to Singletons is using MSMQ. A common way to deal with long-running Duplex services is to make them singletons to be able to store the callbacks. You can avoid this by create a class to manage the callbacks, but then this class effectively becomes a singleton. A far simpler pattern is to take advantage of MSMQ.
Its also worth noting that when searching for Asynchronous method and service invocation patterns the Reactive (Rx) framework seems to come up a lot. This was a framework that was pioneered by a team at Microsoft to "clean-up" code that needs to call methods asynchronously. Its kind of like Linq over Events, and they succeeded in making calling code more elegant. However it has been superseded by the Task Parallel Library (TPL) in .NET 4, more specifically the Task Factory and associated classes. Some say this is not so, but essentially in my humble opinion what can be done out of the box in .NET 4 without an extension framework is the best way to go.
References:
Sunday, May 1, 2011
Professional Motivation
Here's a great short you-tube video recommended to me exploring the idea of modern professional motivation. Money not only is a bad motivator, it actually delivers worse performance once people are paid well already. So what should company leaders use to motivate their staff?
http://www.youtube.com/watch?v=u6XAPnuFjJc
http://www.youtube.com/watch?v=u6XAPnuFjJc
Saturday, April 30, 2011
Why agile software development is like teenage sex
Alexandre de Pellegrin writes:
Why is agile software development like teenage sex?
Today, Romain Gauthier (OCTO Technology, for the moment) sent me a funny post on Agile development. I really like Agile methods but it's so funny that I had to paste it here :
Why is agile software development like teenage sex?
- It's on everyone's mind all the time.
- Everyone is talking about it all the time.
- Everyone thinks everyone else is doing it.
- Almost no one is really doing it.
- doing it poorly
- hopeful it will be better next time
- not practicing it safely
Source:
Tuesday, April 26, 2011
The need for transparency in software development
David Cooksey talks about the Agile principle of transparency specifically in software development.
http://blog.thycoticsolutions.com/2011/04/14/the-agile-virtue-of-transparency/
http://blog.thycoticsolutions.com/2011/04/14/the-agile-virtue-of-transparency/
Saturday, April 23, 2011
Agile Development Principles To Live By
I'm currently reading an excellent book by Robert Martin (aka Uncle Bob) Agile Principles Patterns and Practises in C# (Prentice Hall). I highly recommend it.
There is a fantastic list of agile principles in chapter 1, here's my synopsis of Robert's list.
There is a fantastic list of agile principles in chapter 1, here's my synopsis of Robert's list.
- Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
The smaller the deliverable of software the higher the quality and the less risk of non-delivery. The more often you can deliver the higher the overall quality. All deliverables are production quality code.
- Welcome changing requirements, even late in the development. Agile processes harness change for the customer's competitive advantage. Embrace change, change is good, it demonstrates we have learnt more about the customer's needs. An agile development team should focus on software the is easy to change and maintain, simplifying the adaptive process. In my opinion I would also add to this, communicate the cost of change effectively to stakeholders as well; change does cost and whimsical change should be transparent and visible.
- Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter time scale. Each delivery should satisfy some customer need.
- Business people and developers must work together daily throughout the project. In order to be agile there must be frequent interaction and assessment. A software project is not a fire and forget weapon.
- Build projects around motivated individuals. Give them the environment and support they need and trust them to get the job done. People are always the most important factor in any software project, everything else is secondary and will not compensate for the wrong people on a project.
- The most efficient and effective form of conveying information to and within a team is face-to-face conversation. Speech is a far richer and more concise form of communication over written forms, more information is imparted more quickly and with more detail. Documentation should be created incrementally, but only when NEEDED.
- Working software is the primary measure of progress. The project is 30% done when 30% of all features needed are finished and delivered.
- Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely. It is not a 100metre sprint, its more like a marathon. Care should be taken not to over commit.
- Continuous attention to technical excellence and good design enhances agility. High quality is the key to speed, badly written code generally leads to a do-over. All team members must believe in and be committed to high quality and excellence. They do not create messes that they promise to fix next month.
- Simplicity - the art of maximising the amount of work not done is essential. Take the simplest path that is consistent with the team and project goals. They do not put a lot of importance on solving tomorrow's problems, nor do they try and defend against them today. Rather focus on writing clear quality code that is easy to change.
- The best architecture, requirements, and design emerges from self organising teams. An agile team is a self organising team. Responsibilities should not be handed out, rather let the team decide and come to a consensus on decisions or let them choose who is best able to make these decisions if they feel they cannot contribute. All team members should feel they have influence over decisions made.
- At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behaviour accordingly. The agile team knows that its environment is constantly changes and the best processes from yesterday may not still be best.
This post is meant to be a quick reference of valuable Agile information.
References:
- Agile Principles Patterns and Practises in C# (Prentice Hall)
- www.controlchaos.com
- Clarus Consulting (Thanks to Ed and Bruce for all their valuable advice and help over the last few months).
How to show a dialog in MVVM
In Mvvm you do not want direct references from your controllers (aka View-Models, I find it easier to call them controllers for simplicity). This means you don't want code that specifically calls Window.Show or MessageBox.Show. The reason is basically two-fold:
Message Box Usage
Message boxes pose a problem for unit testing because when open they block the thread from completing, meaning user intervention is required to continue a test. This is not acceptable. To circumvent this, MessageBox use can be accessed via an interface.
The above code works in production, but during testing a mock will need to be injected into the MessageBox property.
- First you will be unable to unit test the controller. Message-boxes or Dialogs popping open will halt the test.
- If you decide to share some code with another project that uses a different UI technology, then not following Mvvm explicitly will prevent this. Also common is stakeholders changing their minds.
The solution is to make use of an Inversion of Control container (aka factory).
Message Box Usage
Message boxes pose a problem for unit testing because when open they block the thread from completing, meaning user intervention is required to continue a test. This is not acceptable. To circumvent this, MessageBox use can be accessed via an interface.
private IMessageBoxService backingMessageBoxService;
public IMessageBoxService MessageBox {
get {
return this.backingMessageBoxService ?? (this.backingMessageBoxService = new WpfMessageBoxService());
}
private set {
// Provided for testing
this.backingMessageBoxService = value;
}
}
}
The above code works in production, but during testing a mock will need to be injected into the MessageBox property.
[Test(Description = "The save action should trigger a message box")]
[Timeout(500)]
public void SuccessfulSaveMessage() {
var controller = new FormController(new ContactDataServiceStub());
var accessor = new FormController_Accessor(controller);
var messageBoxMock = new MessageBoxServiceMock();
accessor.MessageBox = messageBoxMock;
// Click the save button in the same way the View xaml would in production.
controller.SaveCommand.Execute(controller.CurrentContact);
Assert.IsTrue(messageBoxMock.WasShowCalled);
}
public interface IGlassDemoDialog {
event EventHandler Closed;
void Show();
}
And from within your controller you can get a reference to the dialog through the use of an object factory (or using an interfaced property shown previously in this document).
var glassDialog = ObjectFactory.Container.GetInstance<IGlassDemoDialog>();
glassDialog.Show();
This of course assumes you have a registration with the object factory either in the app.config or in startup.
ObjectFactory.Initialize(init => {
// Other config lines here
init.For<IGlassDemoDialog>().Use<WpfGlassWindowDemo>();
});
Finally, your custom interface must be implemented by your View.
public partial class WpfGlassWindowDemo : Window, IGlassDemoDialog { }
[Test]
public void ShowGlassWindowTest() {
var controller = new RighthandController();
var mockRepository = new MockRepository(); // Rhino Mock
var dialogMock = mockRepository.StrictMock<IGlassDemoDialog>();
dialogMock.Expect(dialog => dialog.Show());
mockRepository.ReplayAll(); // Prepare mocks.
ObjectFactory.Initialize(init => {
init.For<IGlassDemoDialog>().Use(dialogMock);
});
Assert.IsTrue(controller.GlassCommand.CanExecute(null));
controller.GlassCommand.Execute(null);
mockRepository.VerifyAll(); // Guarantee all mocks were used appropriately.
}
Subscribe to:
Posts (Atom)