Tutorial :Internal and external interfaces and collections



Question:

What would be the best way to implement the following?

I have a collection of objects that implement an interface, internally I want to be able to expose set and get on the properties and externally only get.

Here's an example of the sort of thing I want... That does't compile.

public interface ITable  {     string Name { get; }  }    internal interface IInternalTable   {     string Name { get; set; }  }    internal class Table : ITable, IInternalTable  {     public string Name { get; set; }     public string ITable.Name { get { return Name; } }  }    public class Database  {      private List<IInternalTable> tables;        public List<ITable>      {         get { return this.tables; }      }  }  


Solution:1

Use this:

public interface ITable  {      string Name { get; }  }    public class Table : ITable  {      public string Name { get; internal set; }  }    public class Database  {      public List<ITable> Tables { get; private set; }  }  

Note: The accessibility modifier used on a get or set accessor can only restrict visibility not increase it.


Solution:2

If Table implements IInternalTable implicitly, and IInternalTable is internal, then those methods will only be accessible internally (because only internal code will be able to use IInternalTable:

public interface ITable  {     string Name { get; }  }    internal interface IInternalTable   {     string Name { get; set; }  }    public class Table : ITable, IInternalTable  {     public string Name { get; set; }     string ITable.Name { get { return Name; } }  }    public class Database  {      private List<Table> tables;        public List<Table> Tables      {         get { return this.tables; }      }  }  

(Also now exposing Table type to avoid issues with lack of covariance... which could also be solved by Database.Tables returning a copy and having a different internal only property.)


Solution:3

It won't compile because there is no conversion between IInternalTable and ITable. Solution is like Koistya Navin suggested:

public class Table {      public string Name {get; internal set; }  }    public class Database {      public IList<Table> Tables { get; private set;}        public Database(){          this.Tables = new List<Table>();      }  }  


Solution:4

This is a common need found in classes representing your domain model, where you want your objects to have a publicly exposed read-only property for the ID, which must be setted internally. A solution I've used in the past is to use a method as a setter:

public interface ITable  {      string Name { get; }  }    internal interface ITableInternal  {     void SetName(string value);  }    public class Table : ITable, ITableInternal  {      public string Name { get; }        public void SetName(string value)      {         // Input validation           this.Name = value;      }  }    public class Database  {      public Table CreateTable()      {          Table instance = new Table();          ((ITableInternal)instance).SetName("tableName");            return table;      }      }  


Solution:5

Actually, I'd recommend hiding the setter-interface entirely as a private interface:

public interface ITable  {     string Name { get; }  }    public class Database  {        private interface IInternalTable       {         string Name { get; set; }      }        private class Table : ITable, IInternalTable      {          public string Name { get; set; }          string ITable.Name { get { return Name; } }      }        private List<IInternalTable> tables;        public List<ITable> Tables      {         get { return this.tables; }      }  }  

That way, nobody other than Database can modify the items in Database.Tables.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »