Search code examples
c#assembly-referencesinterface-implementation

Why am I getting: The type 'IThirdParty' is defined in an assembly that is not referenced. You must add a reference to assembly 'ThirdPartyAssembly'?


Suppose there is third party assembly ThirdPartyAssembly.dll that expose following:

namespace ThirdPartyAssembly
{
    public interface IThirdParty
    {
        void GetInstance(ThirdPartyInfo info);
    }

    public class ThirdPartyInfo
    {
        public ThirdPartyInfo(string instanceText);
        public string InstanceText { get; set; }
    }
}

At one of the solution's project MyAssembly I refer ThirdPartyAssembly.dll and implement following code:

namespace MyAssembly
{
    public abstract class AbstractMyClass1 : IThirdParty
    {
        void IThirdParty.GetInstance(ThirdPartyInfo info)
        {
            info.InstanceText = "some-text";
        }
    }

    public abstract class AbstractMyClass1Consumer<T>
        where T : AbstractMyClass1
    {
    }
}

At second solution project MyAssemblyConsumer I refer MyAssembly (as solution project reference) and implement following classed

namespace MyAssemblyConsumer
{
    class MyClass1 : AbstractMyClass1
    {
    }

    class MyClass1Consumer : AbstractMyClass1Consumer<MyClass1>
    {
    }
}

Everything compiles fine so far. However, when I add IMyClass2 into MyAssembly project that inherits IThirdParty interface with following abstract classes

namespace MyAssembly
{
    public interface IMyClass2 : IThirdParty
    {
    }

    public abstract class AbstractMyClass2 : IMyClass2
    {
        void IThirdParty.GetInstance(ThirdPartyInfo info)
        {
            info.InstanceText = "some-text";
        }
    }

    public abstract class AbstractMyClass2Consumer<T>
        where T : IMyClass2
    {
    }
}

And try to implement following classes into MyAssemblyConsumer

namespace MyAssemblyConsumer
{
    class MyClass2 : AbstractMyClass2
    {
    }
    class MyClass2Consumer : AbstractMyClass2Consumer<MyClass2>
    {
    }
}

I'm getting following compilation error on MyClass2Consumer:

The type 'IThirdParty' is defined in an assembly that is not referenced. You must add a reference to assembly 'ThirdPartyAssembly'

The question why I don't need to refer ThirdParty.dll at first case, but need this reference in the second case?


Solution

  • This is happening because in first case you "hide" your reference to ThirdPartyAssembly.dll. Yes, your public AbstractMyClass1 implements IThirdParty from it, but it implements it implicitly so the only way to call IThirdParty.GetInstance() method is like this:

    var myClass1Instance = new MyClass1();
    var info = new ThirdPartyInfo(); 
    
    (myClass1Instance as IThirdParty).GetInstance(info); // this can be called
    myClass1Instance.GetInstance(info); // <- this method doesn't exists
    

    So at compile time of your MyAssemblyConsumer project compiler doesn't need to know anything about IThirdParty. As you said your first case is compiling successfully, I suppose you don't have any code like this.

    In your second case you expose IThirdParty of ThirdPartyAssembly.dll by your public IMyClass2 interface. In this case compiler must know about IThirdParty interface at compile time (on that line where you defining AbstractMyClass2Consumer<T>), that's why you get this exception.