views:

125

answers:

5

Imagine the following code:

MyService myService = new MyService();
myService.Start();
myService.DoStuff();

The MyService class looks like this:

public class MyService : ClientBase, IMyService
{
...
}

Now I wanted to change the existing code to call this class by using its interface:

IMyService myService = GetMyService();
myService.Start();
myService.DoStuff();

Looks better, but now I get an error on the line containing myService.Start();, since this is an implementation inherited from the ClientBase base class.

What should I do now? Extend the IMyService interface and include the ClientBase interface? That's the only solution I can think of now, but I don't think it's very elegant...

EDIT: The ClientBase class is the one from System.ServiceModel so I can't change anything about this.

+2  A: 

If the Start method is specific to the MyService class, and is not defined in the IMyService interface, you shouldn't be calling Start on a IMyService reference...

On the other hand, if all IMyService implementations should support the Start method, then it should be defined in the interface

You could have something like that :

interface IMyService
{
    void DoStuff();
    void Start();
}

abstract class ClientBase
{
    public void Start() { ... }
}

class MyService : ClientBase, IMyService
{
    public void DoStuff() { ... }
}
Thomas Levesque
Well the calling code relies on the Start method, but of course it doesn't know that it's the method from the base class instead of a method on the interface. And currently there's only one implementation of the interface... I just want to make a new one for unit test purposes (create a stub).
Gerrie Schenck
A: 

IF it needs a start method to be used as an IMyService object, then putting that in the interface makes sense to me. Otherwise a general reconsideration of your design might be in order.

Paddy
I didn't do the design of this, but of course I can change it :)
Gerrie Schenck
A: 

What is the error you are getting?

You should not extend IMyService to include the ClientBase interface. I have had base classes that implemented methods of an interface.

I would verify the Start method on the ClientBase class is public which is required by all interfeaces.

David Basarab
+1  A: 

There is nothing wrong with interface inheritance...

public class ClientBase: IClientBase
{
    public ClientBase()
    {
    }

    public void Start()
    {
    }  
}

public interface IClientBase
{
    void Start();
}

...

public class MyService: ClientBase, IClientBase, IMyService
{
    public MyService()
    {
    }

    public void DoStuff()
    {
    }
}

public interface IMyService: IClientBase
{
    void DoStuff();
}

Then you should be allowed to use your existing code:

IMyService service = new MyService();
service.Start();
service.DoStuff();

An alternative solution would be to make your MyService class implement IClientBase and then just do a cast:

MyService service = new MyService();
(service as IClientBase).Start();
(service as IMyService).DoStuff();

However, I think youl agree the first solution is much better.

James
The ClientBase class is the one from System.ServiceModel and does not have an interface, so this is not an option for me I think. Thanks anyway.
Gerrie Schenck
You have mentioned in your OP that it does *"What should I do now? Extend the IMyService interface and include the ClientBase interface"*
James
There's another class in between, so your first answer was the correct one. I rolled your edit back, thanks.
Gerrie Schenck
A: 

How about aggregating the base class and interface implementation in an abstract class from which MyService will inherit. Instantiate MyService but then let the abstract class be the point of entry. You'd be coding towards a class rather than an interface but i don't know how you can just use an interface since you have concrete implementation to bring with you.

Paul Sasik