views:

169

answers:

1

I'm getting the error:


'Namespace.A' does not contain a definition for 'MyObjectInterface' and no extension method 'MyObjectInterface' accepting a first argument of type ...


I've looked at this and this and neither seems to apply.

The code looks like:

public abstract class Base
{
    public IObject MyObjectInterface { get; set; }
}

public class A : Base
{
    /**/
}

public class Implementation
{
    public void Method()
    {
        Base obj = new A();
        obj.MyObjectInterface = /* something */; // Error here
    }
}
  • IObject is defined in a separate assembly, but:

    • IObject is in a separate assembly/namespace
    • Base and A are in the same assembly/namespace each with correct using directives
    • Implementation is in a third separate assembly namespace, also with correct using directives.
  • Casting to A before trying to set MyObjectInterface doesn't work

  • Specifically, I'm trying to set the value of MyObjectInterface to a mock object (though, I created a fake instead to no avail)

I've tried everything I can think of. Please help before I lose more hair.

edit I can't reproduce the error by creating a test app either, which is why I'm here and why I'm frustrated.

@Reed Copsey: /* something */ is either an NUnit.DynamicMock(IMailer).MockInstance or a Fake object I created that inherits from IObject and just returns canned values.

@Preet Sangha: I checked and no other assembly that is referenced has a definition for an IObject (specifically, it's called an IMailer).

Thing is that intellisense picks up the Property, but when I compile, I get CS0117. I can even 'Go To Definition' in the implementation, and it takes me to where I defined it.

+1  A: 

The error is somewhat consistent with the error you get when you are referencing an assembly that uses a type defined in another assembly and you are not referencing the dependency's dependency.

To fix this add a reference to the assembly containing IObject as a reference to the project containing Implementation.

Here is little diagram. If Assembly2 exposes a type defined in Assembly3 then ASsembly1 must reference Assembly3 as well. The below situation will not work:

_____________             _____________               _____________
| Assembly1  |references  | Assembly2  |references    | Assembly3  |
|           -|------------|->         -|--------------|->          |
|            |            | public     |              | IObject    |
|            |            |  IObject   |              |            |
|            |            |            |              |            |
-------------             -------------               -------------

This is only an issue when a type defined in Assembly3 is accessible through Assembly2. This will be in one of the following situations:

  • Type defined in Assembly2 derives from a type in Assembly3.
  • Method defined in Assembly2 uses a type from Assembly3 as return type or as an argument.
  • Type defined in Assembly2 exposes a type from Assembly3 as a property or a public field.

You will need to add a reference to Assembly3 from Assembly1 to make it compile.

_____________             _____________               _____________
| Assembly1  |references  | Assembly2  |references    | Assembly3  |
|           -|------------|->         -|--------------|->          |
|            |            | public     |              | IObject    |
|            |references  |  IObject   |              |            |
|           -|------------|------------|--------------|->          |
|            |            |            |              |            |
-------------             -------------               -------------
Igor Zevaka
+1 - More detailed explanation than my version.
Toby