Post

Interfaces and partial classes

In .NET on February 13, 2009 by Sid

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.


Leave a Reply