Magnus
Magnus

Reputation: 4714

Automatic (and not refactor-related) extraction of interface from class

I'm relatively new to C# so this may be a somewhat naive question.

Does there exist a way, or can one even be constructed, to construct an interface containing all the public methods/properties of a class?

I find myself in a project using the mocking framework Moq. Moq has an apparently rather common limitation in that it can only handle interfaces and virtual methods. The project's architect has decided to go the interface route, which means every class in the project has an accompanying interface. This means there are loads of interfaces implemented by a single class. Furthermore, the style mandates that interfaces go into their own files. This means there are loads of files in the project.

In my opinion it would be a real improvement if these interface-and-files-just-for-Moq could be a bit less intrusive. Is there no way to have the system (Visual Studio/.Net/C#) create them.

For instance, if writing this

[ExtractAndImplement("IFoo")]
public class Foo
{
    public int Bar(int baz)
    {
        ...
    }
}

would be equivalent to

public interface IFoo
{
    int Bar(int baz);
}

public class Foo : IFoo
{
    public int Bar(int baz)
    {
        ...
    }
}

NB No, Refactor -> Extract Interface does not do what I want. First off, it creates an interface in source code somewhere, so it doesn't reduce the clutter of singly-implemented interfaces. Second, it's an interface I need to maintain explicitly; when I add a public method in the class I need to extract that new method to the correct interface. No, I'd like to have something that's implicit, i.e. interfaces are created on the fly without cluttering the source or the project.

I'm guessing that in Lisp/Scheme it'd be done using macros, and in Haskell using templates.

Upvotes: 1

Views: 181

Answers (3)

Stef Heyenrath
Stef Heyenrath

Reputation: 9820

An option could be to use ProxyInterfaceSourceGenerator which can generate interfaces + proxy classes for defined classes.

Example:

Given: an external existing class which does not implement an interface

public sealed class Person
{
    public string Name { get; set; }

    public string HelloWorld(string name)
    {
        return $"Hello {name} !";
    }
}

Create a partial interface

And annotate this with ProxyInterfaceGenerator.Proxy[...] and with the Type which needs to be wrapped:

[ProxyInterfaceGenerator.Proxy(typeof(Person))]
public partial interface IPerson
{
}

When the code is compiled, this source generator creates the following:

1. An additional partial interface Which defines the same properties and methods as in the external class.

public partial interface IPerson
{
    string Name { get; set; }

    string HelloWorld(string name);
}

2. A Proxy class

Which takes the external class in the constructor and wraps all public properties, events and methods.

public class PersonProxy : IPerson
{
    public Person _Instance { get; }

    /// code here ...
}

Upvotes: 0

Tigran
Tigran

Reputation: 62246

You are probably asking for

The interface language is in Italian (It says "Extract Interface"), sorry, but you got a hint I hope.

enter image description here

Upvotes: 1

Ronald Meijboom
Ronald Meijboom

Reputation: 1564

You can do this in Visual Studio (not in the express version). Use Refactor -> Extract Interface. The cursor needs to be placed on the classname.

For more information:

http://msdn.microsoft.com/en-us/library/fb3dyx26.aspx

You could also look at ReSharper for this option or SharpDevelop.

Upvotes: 1

Related Questions