Interfaces and partial classes

Posted on February 13, 2009

0


What will happen when the following piece of code is compiled?

class Program { static void Main(string[] args) { ICanMove monkey = new Monkey(); monkey.Move(); } } public interface ICanMove { void Move(); } public partial class Monkey : ICanMove { } public partial class Monkey { public void Move() { Console.WriteLine("Moved"); } }
Options:

  1. Compiler error.
  2. “Moved” will be printed.

Answer is b.

How is it useful?

Well, we can apply the same concept to test code that relies upon an auto-generated proxy for a web-service.

Here’s an example to explain what I mean.

Let’s say you have a class that uses a web-service.

public class ServiceUser { public void UseService(ServiceProxy proxy) { proxy.DoSomething(); } }

The class definition for ServiceProxy was generated using a tool (e.g. WSDL).

public partial class ServiceProxy { public void DoSomething() { // Some code here } }

In a test for UseService we want to avoid calling the actual web-service. There are various possible reasons why – performance, usage limits on the web-service, etc.

If we introduce an interface IService like the following:

public interface IService { void DoSomething(); }

And modify ServiceProxy to implement that interface:

public partial class ServiceProxy : IService { public void DoSomething() { // Some code here } }

And also modify ServiceUser.UseService to accept an object implementing that interface:

public class ServiceUser { public void UseService(IService proxy) { proxy.DoSomething(); } }

Then, to test UseService we can create a mock-object implementing IService and pass it into UseService method.

[TestMethod()] public void UseServiceTest() { using (Mockery mocks = new Mockery()) { IService mockService = mocks.NewMock(); Expect.Once.On(mockService).Method("DoSomething"); ServiceUser target = new ServiceUser(); target.UseService(mockService); } }

However it is a good idea to avoid making changes to the auto-generated code for ServiceProxy because they’ll be lost as soon as the proxy is re-generated using the tool.

So that’s where the concept I mentioned in the beginning can help.

Instead of modifying the auto-generated code, just introduce the following empty partial class definition.

public partial class ServiceProxy : IService { }

The actual auto-generated ServiceProxy class definition stays the same as that generated by the tool:

public partial class ServiceProxy { public void DoSomething() { // Some code here } }

That’s it and now you can safely test UseService.

Advertisement
Posted in: .NET