Alternatives to nested interfaces (not possible in C#)

If the end goal is to use this with dependency injection, what's wrong with injecting them into each other instead of nesting?

public interface ICountry
{
    ICountryInfo Info { get; }
}

public interface ICountryInfo
{
    int Population { get; set; }
    string Note { get; set; }
}

and implement as:

public class Country : ICountry
{
    private readonly ICountryInfo _countryInfo;

    public Country(ICountryInfo countryInfo)
    {
        _countryInfo = countryInfo;
    }

    public ICountryInfo Info
    {
        get { return _countryInfo; }
    }
}

public class CountryInfo : ICountryInfo
{
    public int Population { get; set; }
    public string Note { get; set;}
}

Then once you set up your bindings for ICountry & ICountryInfo, CountryInfo will inject into Country whenever Country is injected.

You could then restrict the binding, if you wanted, to only inject CountryInfo into Country and nowhere else. Example in Ninject:

Bind<ICountry>().To<Country>();
Bind<ICountryInfo>().To<CountryInfo>().WhenInjectedInto<Country>();

VB.NET allows this. So, you can create a VB.NET assembly only with the interface definitions that you need:

Public Interface ICountry
  ReadOnly Property Info() As ICountryInfo
    
  Public Interface ICountryInfo
    ReadOnly Property Population() As Integer
    ReadOnly Property Note() As String
  End Interface
End Interface

As for the implementation, C# does not support covariant return types, so you must declare your class like this:

public class Country : ICountry {
  // this property cannot be declared as CountryInfo
  public ICountry.ICountryInfo Info { get; set; }
  
  public class CountryInfo : ICountry.ICountryInfo {
    public string Note { get; set; }
    public int Population { get; set; }
  }
}

You can use namespaces like this:

namespace MyApp
{
    public interface ICountry { }

    namespace Country
    {
        public interface ICountryInfo { }
    }
}

Then in MyApp namespace you can use Country.ICountryInfo which is close to your requirement. Also using alias helps make the code clear.

Tags:

C#

Interface