3
votes

In my C# program, I have a couple of interfaces of my own that I would want to keep internal to my assembly.

internal interface Doable {
    void DoSomething ();
}

internal interface Informable {
    void SomethingHappened (Doable obj);
}

And I have an abstract class as well that cannot be internal, and which abstractly implements the two interfaces like so.

public abstract class MyAbstractClass : Doable, Informable {
    internal abstract void DoSomething ();
    internal abstract void SomethingHappened (Doable obj);

    // Other methods
}

When I do this, however, I get an error that MyAbstractClass does not implement Doable.DoSomething() (and SomethingHappened(Doable obj) as well).

I can change the access modifier of the abstractly implemented DoSomething() to public (which I don't want to in the first place, however), but then SomethingHappened(Doable obj) is a different matter: it complains (rightly so) that the interface Doable is internal (and thusly this method may not have the public access modifier).

I am in a dilemma. I basically want to keep both interfaces and all their concretely implemented methods across all classes in the assembly internal to it with external callers not being aware of their presence.

Wondering how to go about this?

2
You can use an explicit interface implementation (docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…) and forward the method call to an internal abstract method. - kanders84152
Interfaces are contracts. Either make them public or don't sign the contract (don't tell the caller, don't add them to public class at all). That public class with internal abstract members is a code smell. @Servy answer is a good one, another would be to expose public MyPublicAbstractClass which wrap (don't inherit!) some internal MyInternalAbstractClass. - Sinatr
@Sinatr, contracts can be internal as well, there's no valid reason for them not to be. And I disagree about the code smell part: there is a very valid use case for this, when a change to an object needs to be propagated and cascaded across multiple objects within the assembly, without letting this getting known to outsiders. The access modifier thingy keeps getting in the way of this. - Najeeb
My point is: why do you expose internal stuff (you do by using interface)? Why caller should know about it at all? Look at e.g. framework, I don't recall a class implementing some hidden interface like this, because design starts from creating public interfaces. And you are instead trying to create public class containing hidden stuff. Why? Because some hidden methods are using those hidden interfaces methods of public class or what? So you are trying to make that class performing two roles = code smell. Can you show us concrete code? It would be easier to argue and defend if your right. - Sinatr

2 Answers

5
votes

Rather than making the interface implementation abstract, provide a concrete (explicit interface) implementation that calls out to an internal abstract method that actually does the work. This ensures that the interface isn't callable publicly; it's only accessible from the current assembly.

-1
votes

You should use explicit implementation;

internal interface IDoable
{
    void DoSomething();
}

internal interface Informable
{
    void SomethingHappened(IDoable obj);
}
public class MyClass : IDoable, Informable
{
    void IDoable.DoSomething()
    {
        throw new NotImplementedException();
    }

    void Informable.SomethingHappened(IDoable obj)
    {
        throw new NotImplementedException();
    }
}