2

Currently, I'm building a website with 2 layers.

  • Web UI: this is a MVC 4 project, used to interact with users
  • Data Access: this is a C# library. This layer is responsible for interacting with database.

I'm using Ninject for Dependency Injection. Up to now, it's OK. But now, I want to insert a new layer between Web UI and Data Access, called Business Logic. So the architecture would be:

  • Web UI: uses interface from business logic.
  • Business logic: uses interface from data access.
  • Data access: stays the same.

My question is, how should I configure my Ninject in Web UI and Business Logic to achieve what I want? Here is my source code at this time:

Data Access Layer:

Interface IHotelRepository.cs

public interface IHotelRepository
{
    IQueryable<Hotel> Hotels { get; }
}

Concrete class HotelRepository.cs

public class HotelRepository : IHotelRepository
{
    private HotelDbEntities context = new HotelDbEntities();

    public IQueryable<Hotel> Hotels { get { return context.Hotels; } }
}

Web UI layer:

NinjectControllerFactory.cs

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernel;

    public NinjectControllerFactory()
    {
        ninjectKernel = new StandardKernel();
        AddBindings();
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        return controllerType == null ? null : (IController) ninjectKernel.Get(controllerType);
    }

    private void AddBindings()
    {
        ninjectKernel.Bind<IHotelRepository>().To<HotelRepository>();
    }
}

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
    }
}

HotelController.cs

public class HotelController : Controller
{
    private IHotelRepository hotelRepository;

    public HotelController(IHotelRepository repository)
    {
        hotelRepository = repository;
    }

    public ActionResult List()
    {
        return View(hotelRepository.Hotels);
    }

}

Thanks for your help.

mipe34
  • 5,596
  • 3
  • 26
  • 38
Triet Doan
  • 11,455
  • 8
  • 36
  • 69

2 Answers2

2

Not sure to understand your question but I think you don't have to configure Ninject in Business Layer. You should just have one DI configuration in your application, and it should be on Application_start().

Your Business Layer will surely contain Business Objects, and Business Services that will consume Repositories contracts. Those Services would. In this case, you will configure your bindings of services (Bind IHotelService to HotelService) at Application_Start() too.

The design I see is that your controllers will now consume the services (you will inject IHotelService in Controller constructor)

Hope it helps you! Julien

Julien
  • 903
  • 7
  • 12
  • I add you can define Modules with Ninject, inheriting from NinjectModule, that will help you to sort your bindings condigurations – Julien Jul 28 '13 at 15:12
2

Just add bindings for additional required components from bussiness logic to your AddBindings method in NinjectControllerFactory. Ninject is able to resolve chained dependencies like controller -> service -> repository.

mipe34
  • 5,596
  • 3
  • 26
  • 38