0

In my C# project I need to swap data providers in the future so I have created interfaces to build future providers off of. But this is the first time I have worked with interfaces that are "complex" or have collections and sub collections within them.i.e.

My Interfaces:

public interface IPortfolio
{
    string FirstName { get; set; }
    string LastName { get; set; }
    int Id { get; set; }
    ICollection<IDocument> Documents { get; set; }
}

public interface IDocument
{
    string Name { get; set; }
    string ExtensionType { get; set; }
    int Id { get; set; }
    DateTime DateFiled { get; set; }
    int Size { get; set; }
    ICollection<IPage> Pages { get; set; }
}

public interface IPage
{
    int Id { get; set; }
    DateTime DateFiled { get; set; }
    int Size { get; set; }
}

My Classes derived from the interfaces:

public class Portfolio : IPortfolio
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Id { get; set;}
        public ICollection<IDocument> Documents { get; set; }
    }
public class Document : IDocument
    {       
        public string Name { get; set; }
        public string ExtensionType { get; set; }
        public int Id { get; set; }
        public DateTime DateFiled { get; set; }
        public int Size { get; set; }
        public ICollection<IPage> Pages { get; set; }
    }  

public class Page : IPage
    {
        public int Id { get; set; }
        public DateTime DateFiled { get; set; }
        public int Size { get; set; }
    }

Are the classes based on the interfaces correct? Something doesn't seem to be right about the collections in each class. Do I need to implement some sort of iterator?

Any advice would be appreciated.

  • 4
    If an object is just a DTO (properties and no methods) it's OK to skip the interface. Your data providers ought to be able to use the same DTO objects, and for unit testing, the DTOs can be easily mocked as is. But you'll need those interfaces on classes that have behavior, e.g. the class that represents the data source that you hope to replace one day. – John Wu Sep 4 '18 at 16:49
  • 2
    The real value in your case is hiding the implementation of the data access layer behind the interfaces, rather than the entities. – Greg Burghardt Sep 4 '18 at 18:07
  • Do you really need "write access" to the properties after construction of the instances? That's "mutable state" - finding out where some value was changed can be challenging later on. – Bernhard Hiller Nov 5 '18 at 9:12
1

This doesn't seem right because your interfaces should contain behavior rather then properties.

Leave the properties for your classes and have method shells in your interface to represent behavior

Interface:

public interface IPortfolio
{
    //methods to represent behavior
    void SomeMethod();
}

public interface IDocument
{
    //methods to represent behavior
    void SomeMethod();
}

public interface IPage
{
   //methods to represent behavior
    void SomeMethod();
}

And class:

public class Portfolio : IPortfolio
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Id { get; set;}
        public ICollection<IDocument> Documents { get; set; }
        void IPortfolio.SomeMethod
        {
        }
    }
public class Document : IDocument
    {       
        public string Name { get; set; }
        public string ExtensionType { get; set; }
        public int Id { get; set; }
        public DateTime DateFiled { get; set; }
        public int Size { get; set; }
        public ICollection<IPage> Pages { get; set; }
        void IDocument.SomeMethod
        {
        }
    }  

public class Page : Ipage
    {
        public int Id { get; set; }
        public DateTime DateFiled { get; set; }
        public int Size { get; set; }
        void Ipage.SomeMethod
        {
        }
    }

Your interface should contain a shell of what behavior your interface should implement. This way you will have common methods that will represent the behavior of each class to implement as you will.

If you want to use properties in your inheritence, you better use an abstract class to implement this.


Edit to calrify:

read this article to understand more -
Why Do We Use Abstract Class?

  • But if you have future unknown providers wouldn't you want the interface defined so that the new providers can be built to the contract of the interface and consumed? – John S Sep 5 '18 at 12:55
  • This is the exact reason why interface contains methods and is not recommended to contain properties. – Barr J Sep 5 '18 at 13:16
  • OK if the interface defines the signature of a method that returns something other than a basic datatype where should that complex datatype be defined? That is what I was trying to do with IPortfolio, etc... – John S Sep 5 '18 at 13:59
  • 1
    Abstract class :) – Barr J Sep 5 '18 at 15:36
  • Abstract classes is rarely a solution to anything. It is an artifact from lesser languages. The question is marked with C#. Don't try to force problems from Java or C++ onto C#. C# does very well without abstract classes. – Bent Sep 5 '18 at 22:12
0

For DTO's you don't need an interface. You'll have the same DTO objects no matter which data store you have.

What you can do, is adding an interface to your data layer. Example:

public interface IPortfolioDataAccess
{
  Save (Portfolio portfolio);
}

public class MySqlPortfolioDataAccess : IPortfolioDataAccess
{
  Save(Portfolio portfolio)
  {
    //Save to MySql
  }
}

public class SqlServerPorftolioDataAccess : IPortfolioDataAccess
{
  Save(Portfolio portfolio)
  {
    //Save to Sql Server
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.