C# Interfaces

pcpal4
pcpal4 used Ask the Experts™
on
I'm relatively new to .Net and working on a new project using VS2010.  The final project will involve multiple separate distinct solutions.  The customer does not want everything under one solution.  I've wrote some skeleton code below but I haven't done much with interfaces so I'm getting stuck.  

Solution 1 : MVC4 WEBAPI
Solution 2:  Class Library  
The dll created by the class library will be added to the webapi project as a reference.  
Class Library Project: (creates My.MedList.dll)
1. Models folder with various data related .cs files
2. Repository folder that will contain:
     -- DbRepository class which holds the SQL statements and references another dll to
        build the database connections and returns data from the database. This class should
        be internal so it can not be referenced directly by applications
     -- IDbRepoository class which is the interface for the DbRepository class and should be
        used only by the MedList class
3. Main project classes -
     -- MedList class  - contains any business logic needed, implements IMedList
     -- IMedList class - the interface that everything should interact with
---------------------------------------------------
What should happen:
Contoller >> IMedList.cs >> MedList.cs  >> IDbRepository.cs >> DbRepository.cs
Controller << IMedList.cs << MedList.cs << IDbRepository.cs << DbRepositry.cs << data

Controller will then reference the models in My.MedList.Models and serialize the data to json.

The only piece of MyMedList.dll that the controller and/or applictions should be able to see/access is IMedList.cs.  The rest should be 'internal' to the library and should not be able to be instanciated. The customer wants to essenitally force mobile apps/internal applications to either use the webapi or reference the dll but only be able to use the IMedList interface.  This way as long as the interface doesn't change, the database, etc. can be swapped out without impacting the UIs. It should also help eliminate duplicate sql and business logic between applications.

Please see Questions in the sample code.   Looking for the easiest/best way to accomplish this.
-----------------------------------------------------
A simple code example:

Solution 1 MVC4 WEBAPI Controller
-- Web.Mvc project references My.MedList.dll

using My.MedList;
using My.MedList.Models;
namespace My.API.Web.Mvc.Controllers
{
  public class MedListController : ApiController
  {
        public readonly IMedList _medlist;

        public IQueryable<Meds> Get(int pt, int year)
        {
            _medlist.GetMedList(pt, year);
???  This is where I need to "instanciate" My.MedList.IMedList, but it is not possible
            to instanciate an interface with 'new'.  
            What is the best way to access IMedList to get the data?
        }
  }
}
-------------------------------------------------------
Solution 2

//--Sched.cs (Main Project folder)--

using My.MedList.Models;
using My.MedList.Repository;
namespace My.MedList
{

??? should this class be abstract
  internal class MedList : IMedList    
  {
     private readonly IDbRepository _repository;

     public IQueryable<Meds> GetMedList(int pt, int year)
     {
        IList<Meds> meds = new List<Meds>();
             
        meds = (IList<Meds>)_repository.GetMedList(pt, year);
??? What is the best way to access IDbRepository to get the data?

        ...
         business logic on meds list
        ...

       return (meds.AsOueryable());

     }
                 
  }
}

//--IMedList.cs (separate file in Main Project folder)--
using My.MedList.Models;
namespace My.MedList
{
  public interface IMedList
  {
     IQueryable<Meds> GetMedList(int pt, int year);
  }
}
- - - - - - - - - -
//--DbRepository.cs (Repository folder)--
using My.MedList.Models;
namespace My.MedList.Repository
{
  internal class DbRepository : IDbRepository
  {

    public IQueryable<Meds> GetMedList(int pt, int year)
    {
       IList<Meds> meds = new List<Meds>();
 
       ...
        database connection, sql statement, execute database command,
        use reader and models to build IList object
       ...
 
       return (meds.AsQueryable());
    }
  }
}

//--IDbRepository.cs (separate file in Repository folder)--
using My.MedList.Models;
namespace My.MedList.Repository
{

??? could this be internal interface...
  interface IDbRepository      
  {
       public IQueryable<Meds> GetMedList(int pt, int year);
  }
}
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
An interface only defines the 'contract' that implementing code must follow.  Since there is no code whatsoever in an Interface ( the interface defines the methods with their signatures, but not the code within the methods), there is no way to 'instantiate' an interface.  That is what happens when the interface is IMPLEMENTED.  A class which implements an Interface must have code for each and every one of the methods that are defined in the Interface.  

An interface serves to guarantee that any code which accesses an class which implements that interface can be guaranteed that the implementing class will have certain defines behaviours  - without having to be concerned with HOW those behaviours are actally coded.  The interface defines the appearnace of the 'balck box' without specifying what actually happens INSIDE that 'black box'.

AW
I think you should take a look at dependency injection and IOC containers with ASP MVC. For example

http://weblogs.asp.net/shijuvarghese/archive/2010/04/30/dependency-injection-in-nerddinner-app-using-ninject.aspx
http://www.mikesdotnetting.com/Article/117/Dependency-Injection-and-Inversion-of-Control-with-ASP.NET-MVC

There are quite a few options like Unity, MEF, StructureMap, NInject. The DBRespository for example should be injected and most likely using Config settings.

As for internalizing IDbRepository (though Im not sure I fully understood)

It is possible to define internal interfaces that can only be accessed from friend assemblies. Search for Friend assemblies and you should find ample docs on how to declare friendship between assemblies.

However, I think it does not make sense to use that features for such esoteric reasons. IDbRepository qualifies to be public even though it may only be intended to be used by services and never directly consumed by the UI.

Whats wrong with putting Repository assemblies (all of them) with public interfaces specific to repositories in a folder say "repository" under bin?

If you hide IDbRepository what do you have in mind for Testcases for repositories? Do you want to use friend specifiers for unit test assemblies as well?
Most Valuable Expert 2012
Top Expert 2008
Commented:
That sounds like a facade, that is an abstract base class, that has the behavior that the caller needs, but they would have to implement a concrete class.  The contract could be defined with abstract methods, or an interface.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial