5

I have used Ninject in MVC Web application without any problem for injecting the business logic classes. But i want to inject the data access classes to the constructor of business logic classes. Logic layer is a class library and has no Program.cs class or entry point.

Data access class

 public class DataAccessClass
 {
   public void Insert(Product product)
    {
        new SqlObj().Insert(Product);
    }
 }

Data access class interface

 public Interface IDataAccessClass()
 {
   void Insert(Product product);
 }

Business logic class

 public class ProductLogic()
 {
     IDataAccessClass _dataAccessClass;

    //DataAccessClass should be injected here using Ninject
     public ProductLogic(IDataAccessClass dataAccessClass)
     {
        _dataAccessClass=dataAccessClass;
     }
     public InsertProduct(Product product)
     {
         _dataAccessClass.Insert(product);
     }
 }

This is what I need I have a 3 layer application and the layers are:

  • Web: Presentation Layer (ASP.NET MVC) --> only sees BLL
  • BLL: Business Logic Layer --> only sees DAL
  • DAL: Data Access Layer

So the Web layer doesn't know anything about my DAL layer. I have repository interfaces and concrete classes in my DAL, which are used in BLL layer in business logic classes. The question is, in order to decouple DAL and BLL, how do I setup Ninject to inject my repository implementations to the BLL layer?

adricadar
  • 9,971
  • 5
  • 33
  • 46
VIVEK P S
  • 315
  • 2
  • 15
  • Where you register this object to be injected and how you try to use NInject? – adricadar Apr 18 '15 at 14:05
  • @adricadar When I added Ninject to inject the logic classes in the constructor of controllers ,the Nuget Package automatically added the implementation inside the App_Start folder.But in a class library since there is no entry point or program.cs, how can I add the Ninject module? – VIVEK P S Apr 18 '15 at 14:10
  • @VIVEKPS you shouldn't do any wiring up in you library, as this then ties your library to NInject. instead do all of the wiring up in the start point of the application that is going to use your library. this can then wire up you library's components and everything else – Sam Holder Apr 18 '15 at 19:50
  • @Sam Holder It is not about application using library.Actually one library is using the other. And I need to inject the dependency of one class inside one library to a class inside the another library – VIVEK P S Apr 20 '15 at 11:19
  • 1
    @VIVEKPS you should read up about the theory behind dependency injection and how to implement it without a framework like NInject, and read up about the [composition root](http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-the-context-of-dependency-injection). In reality your web app does know about the full hierarchy of your dependencies and this is the place where everything should be wired up. Your startup location should create the DAL and inject it into the BLL it creates. – Sam Holder Apr 20 '15 at 11:51

2 Answers2

4

I've just come across this post and had the same potential misconception as the original poster until I understood that:

Class libraries are just that, libraries. They do not control the injection of dependencies. The DI is configured in whichever application uses those libraries (be it console, ASP.NET, WPF, WinForms or whatever) even when those injections are solely in the class libraries.

I came across this issue when moving my core models and entity framework (using unit of work) into a separate class library for re-use. I spend a couple of hours trying to work out how that class library configures its DI, when in the end it was the MVC web app that references the class library that needed to handle it.

In other words, in the bootstrapper of my actual app I needed to bind the Interfaces / Concrete Classes that are used in my referenced class libraries.

JWhitley
  • 41
  • 1
  • This should be the accepted answer. Class libraries cannot handle DI. You could create a Ninject module or registrations class in this library which can be called from the application's entry point to resolve dependencies even if they only exist in your class library – Rob Husband Nov 25 '20 at 11:26
3

Install NInject with Nuget

Install-Package Ninject

You can create a method to register the objects. You need to register all the dependencies required to create the object.

public static void Register(IKernel kernel)
{
    kernel.Bind<IDataAccessClass>().To<DataAccessClass>();
    kernel.Bind<ProductLogic>().ToSelf();
}

Create a new instance of StandardKernel and call Register to register the objects.

To get an instance of an object you simple call Get<> method and you will get a new insance of that object. There are other methods too.

static void Main(string[] args)
{
    var kernel = new StandardKernel();
    Register(kernel); // register the objects

    var productLogic = kernel.Get<ProductLogic>(); // create instance
}

To solve the problem that, only BLL sees DAL you can add a new project (class library) where you install NInject and create that Register method. You can reference this class library in Web project and register the entities.

Objects

public class Product
{
}

public class DataAccessClass : IDataAccessClass
{
    public void Insert(Product product)
    {

    }
}

public interface IDataAccessClass
{
    void Insert(Product product);
}


public class ProductLogic
{
    IDataAccessClass _dataAccessClass;

    //DataAccessClass should be injected here using Ninject
    public ProductLogic(IDataAccessClass dataAccessClass)
    {
        _dataAccessClass = dataAccessClass;
    }
    public void InsertProduct(Product product)
    {
        _dataAccessClass.Insert(product);
    }
}
adricadar
  • 9,971
  • 5
  • 33
  • 46
  • Sorry, I don't understand this. Where do I write this main method in ProductLogic class library? – VIVEK P S Apr 19 '15 at 15:13
  • @VIVEKPS You write this method where you want to use NInject. For example, in MVC project this method was already written and you just use it. This method usualy is written in UI layer. If you just want to use NInject in multiple UI layers project this method is written in a separate class library that is referenced in that UI layers. – adricadar Apr 19 '15 at 15:31
  • I don't want to use this in UI layer. I need to access data layer in business layer.There is no entry point in the business layer – VIVEK P S Apr 20 '15 at 06:29
  • @VIVEKPS Where you use business layer? – adricadar Apr 20 '15 at 09:33
  • This is what i need I have a 3 layer application and the layers are: - Web: Presentation Layer (ASP.NET MVC) --> only sees BLL - BLL: Business Logic Layer --> only sees DAL - DAL: Data Access Layer So the `Web` layer doesn't know anything about my `DAL` layer. I have repository interfaces and concrete classes in my `DAL`, which are used in `BLL` layer in business logic classes. The question is, in order to decouple `DAL` and `BLL`, how do I setup Ninject to inject my repository implementations to the `BLL` layer? – VIVEK P S Apr 20 '15 at 10:30
  • Why update the question if you have already accepted the answer? – Sam Holder Apr 20 '15 at 12:22
  • This answer makes no sense. Didnt answer the fundamental question of where do you put the bindings in a class library. There is no MAIN in a class library, this is not a console application. I'll continue searching for how to setup the bindings but this answer along with the bad english second sentence. It's a matter of fact there is no main in any of the layers he mentioned in the OP. – Mike Feb 26 '18 at 12:05
  • @Mike Take everything with a grain of salt. You can create a special class 'DependencyAssembly' in your class library and register the dependency tree there. Thank you for your feedback and taking the time to 'english proof' my answer. – adricadar Feb 26 '18 at 12:28
  • @adricadar I understood that I needed to create a special class for binding the dependencies but as I stated before your answer doesnt tell anyone how those dependencies are binded every time there is a call to a class in a class library that requires their dependencies injected. As I said the OP has no main in any of the projects that he mentioned. – Mike Mar 01 '18 at 11:48