2

Say I have an Interface like this in a project called "Interface":

public interface TestInterface
{
    string Operation();
}

and class which implements it. This class is located in another project "Class":

public class TestClass : TestInterface
{
    public TestClass() { }

    public string Operation()
    {
        return "This is an Operation";
    }
}

My client does something like this (which is again in a different project "Client"):

class Program
{
    static void Main(string[] args)
    {
        TestInterface i = new TestClass();
        i.Operation();
    }
}

My question is related to this line:

TestInterface i = new TestClass();

By adding this line, I'm actually forced to add a references to both "Interface" as well as "Class" projects from my "Client" project. So why all this fuss? Can't I directly refer to the "Class" without keeping the "Interface" in between? Is there any way to access the methods via Interface only (without making a reference to the implementation Class)? Am I missing something here?

Sandeep
  • 5,581
  • 10
  • 42
  • 62
  • The client code is creating an instance of `TestClass`. How would it be possible to do that without access to the assembly that defines it? – Jon Jan 24 '13 at 10:01
  • @Jon: Yes, I understand that. But then, what is the actual advantage of accessing methods through an interface, if still we need to refer the class? – Sandeep Jan 24 '13 at 10:02
  • You can acces multiple instances that implement the same interface and treat them as the same object. – BBQ Jan 24 '13 at 10:04
  • 1
    That's a completely unrelated question that relates to OO design. An obvious answer is "you can write a method that accepts an `ISomething` without knowing what its type will be". In fact there is no need for *any* type implementing `ISomething` to exist at the time you write the method. – Jon Jan 24 '13 at 10:04
  • Do you know what Dependency Injection mean? – Ilya Ivanov Jan 24 '13 at 10:05

5 Answers5

2

Is there any way to access the methods via Interface only

Yes, there is. You can dynamically load an assembly with TestClass without referencing it, create its instance via Activator.CreateInstance and cast it to interface type:

var assembly = Assembly.Load(...);
var typeFromAssembly = assembly.GetTypes()...;
var myInterfaceVar = (TestInterface)Activator.CreateInstance(typeFromAssembly);

...or... you may use one of existing DI-frameworks (e.g. MEF) and do the same thing more right way:

[Import]
private TestInterface myInterfaceField;

or:

var myInterfaceVar = compositionContainer.GetExportedValue<TestInterface>();

Depending of the way you prefer, you may ask more concrete question.

Dennis
  • 37,026
  • 10
  • 82
  • 150
  • 1
    And how does this change the bottom line? You still need the assembly, and you get to do more work on top. – Jon Jan 24 '13 at 10:05
  • @Jon: but you don't need reference this assembly. – Dennis Jan 24 '13 at 10:09
  • So? I don't think the issue here is that right click => add reference is too hard. – Jon Jan 24 '13 at 10:11
  • @Jon: Add reference isn't hard. :) But what about the case, when you need to change used `TestInterface` implementation without recompiling the code, which works with `TestInterface` only and can't know about any implementation? – Dennis Jan 24 '13 at 10:13
0

To make your code completely independent from implementation of TestInterface use Dependency Inversion. This could be achieved by some Dependency Injection framework.

E.g. with Unity you can configure implementation via xml

<register type="TestInterface" 
          mapTo="Foo.Bar.TestClass, Foo.Bar" />

And your code will depend only on Unity (no references to implementation):

TestInterface i = Container.Resolve<TestInterface>();
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
0

In that particular sample, there is no advantage.

But imagine a method:

public void Foo(ITestInterface handler)
{
    handler.Operation();
}

Now, Foo operates only on the interface and it doesn't care what concrete class implements this interface. You could now call Foo with an instance of TestClass or with TestClass2, which could be defined in a different assembly.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
0

you can achieve the behavior you have described via using IOC. Unity is a dependency injection container which allows to create instances without manually creating instances.

For instance, if you were to register your class and interface to unity, you would directly use the interface;

TestInterface i = Container.Resolve<TestInterface>();
daryal
  • 14,643
  • 4
  • 38
  • 54
0

You have interface so that your app can have plug in's..

So basically you share your Interface dll to anyone who wants to make a plugin app for your app and then you can cast that new plugin class to the interface and invoke methods on it..

If you dont cast the class to the interface,how on earth are you going to make the plugin class work for your app..

Anirudha
  • 32,393
  • 7
  • 68
  • 89