Question

I have an assembly inside an application defining the following interface:

public void Method1()

Then I have an assembly plugin implementing this interface. It is discovered and loaded at runtime.

Latter on I modified the interface to include a new method:

public void Method1()
public void Method2()

And I created a new assembly plugin implementing the new version of the interface.

Is there a way to deploy only the new interface and the new plugin on the application? Currently the client will never call Method2() on the first plugin so it shouldn't be a problem (I'm ok throwing an Exception if at any point Method2 gets called on the 1st plugin).

I thought I could do that but I'm getting a TypeLoadException saying:

Method 'Method2' in type 'Provider2.Class2' from assembly 'Provider2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

(which is true but as Method2 is not called shouldn't be a problem)

Was it helpful?

Solution 2

as Method2 is not called shouldn't be a problem

That's not how types in .Net work. If your class claims that it implements an interface, then it simply has to implement that interface.

What you describe is similar to duck typing and .Net does not use that.

OTHER TIPS

You should not modify that interface.

Interfaces are typically used in one of two major ways:

  1. They're used completely internal to the application
  2. They're public, in the sense that others can create things like plugins and whatnot that implement or use the interfaces

In the first option, you're of course free to do whatever you want with it, like adding new methods to it. It's your own problem if that creates a lot of compiler errors, and you can "easily" fix those as well.

In the second option, you should never modify that interface. Instead you should create a new interface with the new methods, and then write your code so that it supports both the old and the new interface.

Unless, of course, you want to disallow the old classes from working altogether, then you're back to doing whatever you want.

So the answer here is that you should not modify that interface. Instead create a new interface with the new methods, and support both the old version and the new version.

You should strive to use this approach any time you change the interface, and this includes more types of changes than just adding a method.

If you change the meaning of the interface, or fix major non-catastrophical bugs, you might want to introduce a new interface, and let the old interface have the old bugs. Someone might have written code that relies on the old behavior, good or bad, and you "fixing" this might break things that used to work, even if the compiler doesn't complain.

For instance, let's say that you pass the result of a comparison to a method. Your documentation states that the values will be negative if the comparison results in a < result, positive for a >, and 0 for a ==.

Then you suddenly discover that you're not returning -1, 0 or +1, you're returning -N, 0 and +N, where N is some number that is a byproduct of the comparison, for instance the result of A-B, so in the next version you change that to be -1, 0 and +1.

Some code might rely on the fact that the values also represent more than just the result of the comparison, but is indeed -N, and thus you fixing this problem breaks that code.

Of course, relying on undocumented behavior is always bad, but again, your customers would more than probable be hung up on the fact that the code used to work, and your update broke it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top