1

I've outsourced my enterprise level project to a freelancer and I got a quite good setup too. But now that contract has finished and the person has also moved to a new technology, in other words not willing to extend the contract. Now I'm looking into this code on myself. I do have a 2 3 years of background in C# and MVC. Below is a rough idea of my application architecture. Hopefully I've tried my best to abstract the architectural details of an enterprise level application. Please let me know if you need further brief on any of the questions.


All my Entities are defined as C# POCO classes as:

public class Product : BaseEntity
{
   public int ProductId { get; set; }
   public string ProductName { get; set; }
}

Now I've a IDbContext like as :

public interface IDbContext : IDisposable
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity;      
}

Base Entity is a Partial POCO class that each POCO entity is inheriting. Here is a class that implements this IDBContext as:

public class MyObjectContext : DbContext, IDbContext
{
    public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
    {
        return base.Set<TEntity>();
    }
}

Now I've defined a IDbContextFactory that is responsible for providing the DBContexts as :

public interface IDbContextFactory
{
    Lazy<IDbContext> CreateDbContext();
}

The class implementing this IDBContextFactory interface is having below structure :

public class MyDbContextFactory : IDbContextFactory
{
    public MyDbContextFactory(string dbConnectionString)
    {
        _dbConnectionString = Settings.DbConnectionString;
        _dbContext = CreateDbContext();
    }

    public IDbContext CreateDbContext()
    {
        IDbContext dbContext = new IDbContext(() => CreateNewContext());
        return dbContext;
    }

    private MyObjectContext CreateNewContext()
    {
        return new MyObjectContext (_dbConnectionString);
    }
}

Here IRepo Pattern comes into role as:

public partial interface IRepository<T> where T : BaseEntity
{
    T GetById(object id);
}

Now the Repository class implementing this Interface is as below :

public partial class EfRepository<T> : IRepository<T> where T : BaseEntity
{
    private readonly Lazy<IDbContext> _dbContext;
    private readonly IDbContextFactory _dbContextFactory;
    private readonly Lazy<ObjectStateManager> _objectStateManager;

    public EfRepository(IDbContextFactory dbContextFactory)
    {
        _dbContextFactory = dbContextFactory;
        _dbContext= _dbContextFactory.CreateDbContext();
        _objectStateManager= new Lazy<ObjectStateManager>(() => ((IObjectContextAdapter)_dbContext.Value).ObjectContext.ObjectStateManager);
    }

    public T GetById(object id)
    {
        return this.Entities.Find(id);
    }
}

Till now we are done with the Infrastructure level setup for DB Access Management. Now the thing is to utilize this setup into Controllers(as I'm having directly accessing Repositories from Controllers) to as below :

public class CountryController: BaseController
{
    private readonly Lazy<IRepository<Country>> _countryRepository;

    public CountryController(Lazy<IRepository<Country>> countryRepository)
    {
        _countryRepository = countryRepository;
    }

    public Country GetCountryById(int id)
    {
        Country country = _countryRepository.Value.GetById(id);

        if (country != null)
            return country;
        else
            return null;
    }

Hopefully all above is clear. Now here are the some questions that I need to be answered :

1) Why we are having this layered flow like as:

IDBContext -> IDBContextFactory -> IRepository <T>

and then finally using this IRepository into Controllers for accessing Data objects. In other words why we are relying on Interfaces instead of actual Class Objects while implementing Constructor Injection for Country Controller ?

2) Is this the correct approach for a Enterprise level Application as it should be much scalable for future purpose. If there is any other then I would be glad to know about that ?

3) In Controller's constructor I've used Lazy>, so what's the purpose of this Lazy and is it beneficial actually If yes then in what way ?

Amy
  • 59
  • 1
  • 6
  • 1
    Hope this gives you some idea : http://stackoverflow.com/questions/2026054/why-do-we-use-interface-is-it-only-for-standardization – Durgesh Chaudhary Jan 29 '15 at 09:05
  • Pick out of the shelf the UML architecture diagrams and the design document you have signed-off with your subcontractor – xmojmr Jan 29 '15 at 11:02
  • Remove the `Lazy` from your repository-injections. It is unnecessary and should not be part of your 'contract'. You can always use a proxy class that adds the lazyness. – Maarten Jan 29 '15 at 11:44

1 Answers1

3

This is Design Pattern. And it is called Dependency Injection.

The EfRepository class demands its dependencies be injected using its constructor—this is known as constructor injection. We could also allow the dependencies to be injected through a public property, known as setter injection.

One of most important features of the MVC pattern is that it enables separation of concerns. We want the components in our application to be as independent as possible and to have as few interdependencies as we can manage.

In our ideal situation, each component knows nothing about any other component and only deals with other areas of the application through abstract interfaces. This is known as loose coupling, and it makes testing and modifying our application easier. Interfaces help us decouple components.

What we need is a way to obtain objects that implement a given interface without having to create the implementing object directly. The solution to this problem is called dependency injection (DI), also known as Inversion of Control (IoC).

DI is a design pattern that completes the loose coupling we started by adding the interface.

Quotes are copied from the 3rd chapter of this book.

Farhad Jabiyev
  • 26,014
  • 8
  • 72
  • 98
  • Hi Farhad, Thanks for your valueable response. I got the point about DI and Design Pattern. Now could you please tell me what will be the drawback if I use Direct Class reference instead of interface instead of Interface in Constructor Injection ? – Amy Jan 29 '15 at 11:00
  • @Amy Glad to help. have you ever used UnitTesting? For example, it will increase testability of your application. The tightly coupled architecture is unsuitable for unit testing. And again, the main point is to seperate the concerns. I really recommend you to read Chapter 3 and 6 from the book which I gave the link in answer. You will learn how to use Ninject and Moq. – Farhad Jabiyev Jan 29 '15 at 11:08
  • Thanks mate! I appreciate your co-operation. I'm going through the suggested chapters. See ya ! – Amy Jan 29 '15 at 11:28