跳至內容

使用者:Jasonmail04/sandbox

維基百科,自由的百科全書
Ninject
Ninject logo
程式語言LINQ
平台.NET languages (C#, F#, VB.NET)
文件大小1.3 MB
網站www.ninject.org

Ninject is one of the newest framework for .NET application. It helps to split application into a collection of sloppy-coupled, highly-connected pieces, and combine them together in a flexible manner by using dependency injection technique. It makes user's job easy to write, reuse, test, and modify their code to support latest software's architecture. Ninject makes use of the lightweight code generation in the CLR(Common Language Runtime), and supports most major facilities offered by the competing frameworks.[1]

Why use Ninject?[2][編輯]

Every software development project involves breaking the whole component into many individual components, and later combining them together in-order for the software to work. Ninject helps you to solve this. First, many other frameworks use XML configuration files to guide the framework, this causes the configuration to be more complex and verbose, since we often need to write out the assembly-qualified type name for each types. However, Ninject provides a fluent interface to declare type bindings.

Furthermore, Ninject aims to keep things simple. Most of other frameworks are complicated and heavyweight, and it needs user to add several assembly dependencies to project.

Third, Ninject have an extremely powerful form of binding called "contextual binding". Ninject can be aware of its environment, and alter the implementation for a give service during activation.

Features[編輯]

  • Ninject has many advanced features. Ninject is designed in a way to use features, that are often necessary, with ease. You need not know all the advanced features for using the basic.
  • Ninject is developed with only .NET base library. It doesn't use any third party libraries. Thus making the application which uses ninject, to deal with very minimal dependencies.
  • CLR has a light-weight code generation feature which is used by Ninject to make the performance better.
  • Ninject doesn't use any XML configuration files like other dependency injectors.
  • Ninject is component-based-architecture. Which means the software can be customized according to the application and usage.
  • Ninject can also inject different implementations of a service during rum-time. i.e; depending on the context.

History[編輯]

There were many IOC Containers prior to Ninject. Ninject version-1 wasn't the first Dependency Injection container. Ninject version-2 wasn't backward compatible with version-1. Developers wanted something new which doesn't rely on XML configuration files to guide the framework to pull up every component of your application. Ninject version-3 uses " embedded domain-specific language" to declare the bindings.

Getting Started[編輯]

Download[編輯]

Ninject can be easily downloaded from Ninject[3]

Souce code of Active Job available on GitHub.[4]

Hello Ninject![1][編輯]

Once we have Ninject DLLs in our drive, the first step is to add a reference to Ninject.dll in our library directory.

Add a new class to our project and call it SalutationService:

class SalutationService
{
    public void SayHello()
    {
        Console.WriteLine("Hello Ninject!")
    }
}

Add using Ninject to the using section of Program.cs. Add the following lines to Main method:

using (var kernel = new Ninject.StandardKernel())
{
    var service = kernel.Get<SalutationService>();
    service.SayHello();
}

There shows how Ninject works in the simple way. We don't need to add any configuration or annotation. Ninject automatically inject in the previous example and print the "Hello Ninject!" for us.

For the detail at the Main method here, firstly, we created a kernel object by instantiating StandardKernel. Kernel is the start point of creating dependency graph, and StandardKernel is the default implementation of such an object. In the example, the graph only consists of one type, SalutationService. We didn't call the constructor of SalutationService in the Main method. Instead, our container(kernel) do it automatically. Get method returned an instance of the given type we required. The Get method was provided with the root type(SalutationService) of our dependency graph and returned the graph object.

Dependency Injection With Ninject[4][編輯]

The most amazing part for Ninject is don't need to spend time on doing the "busy work" of creating and connecting objects by hand.

How Ninject constructs types[編輯]

Ninjects calls one of the constructors on our types, just like we would do Dependency Injection by Hand. When asked to instantiate an object, Ninject will look at the type's of available public constructors and pick the one with the most parameters it knows how to resolve. This means that if we want to resolve and have dependencies injected anything to the service class, Ninject is able to instantiate our objects.

Examples[5][編輯]

Defined the ITaxCalculator interface and a trivial implementation TaxCalculator as follows:

decimal CalculateTax(decimal gross);
public class TaxCalculator : ITaxCalculator
{
    private readonly decimal _rate;
 
    public TaxCalculator(decimal rate)             
    {
        _rate = rate;
    }
 
    public decimal CalculateTax(decimal amount)
    {
        return Math.Round(_rate * amount, 2);
    }
}

Now, if one of more classes need to use an ITaxCalculator implementation to fulfill their responsibility, we can say that an implementation of ITaxCalculator is a dependency to them.

using (IKernel kernel = new StandardKernel())
{
    kernel.Bind<ITaxCalculator>()
          .To<TaxCalculator>()
          .WithConstructorArgument("rate", .2M);
 
    var tc = kernel.Get<ITaxCalculator>();
    Assert.Equal(20M, tc.CalculateTax(100M));
}

Through the interface, we instructed the kernel how to bind requests for ITaxCalculator to TaxCalculator class, passing to its constructor a given tax rate. Now, a Sale class models an ongoing transaction. The class depends on a ITaxCalculator to compute the final price of the shopping cart.

public class Sale
{
    private readonly ITaxCalculator taxCalculator;
 
    public Sale(ITaxCalculator taxCalculator)
    {
        this.taxCalculator = taxCalculator;
    }
 
    // more stuff....
 
    public decimal GetTotal()
    {
    // use the tax calculator to calculate the total
    }
}

Create the sale based on the preceding example:

kernel.Bind<ITaxCalculator>()
          .To<TaxCalculator>()
          .WithConstructorArgument("rate", .2M);
var sale = new Sale(kernel.Get<ITaxCalculator>());>

Or let Ninject to find out how a Sale should be built based on the binding information it received:

kernel.Bind<ITaxCalculator>()
          .To<TaxCalculator>()
          .WithConstructorArgument("rate", .2M);
var sale = kernel.Get<Sale>();

Ninject is able to build a Sale class to take care of fulfilling the dependencies behind the scenes.

External links[編輯]

References[編輯]

  1. ^ 1.0 1.1 Baharestani, Daniel. Mastering Ninject for Dependency Injection. PACKT. 2013. 
  2. ^ Ninject. CodePlex. [2016-09-13]. 
  3. ^ Ninject. 
  4. ^ 4.0 4.1 GitHub. 
  5. ^ Ricciardi, Stefano. Ninject Mini Tutorial. 

Why use Ninject?[1][編輯]

Every software development project involves breaking the whole component into many individual components, and later combining them together in-order for the software to work. Ninject helps you to solve this. First, many other frameworks use XML configuration files to guide the framework, this causes the configuration to be more complex and verbose, since we often need to write out the assembly-qualified type name for each types. However, Ninject provides a fluent interface to declare type bindings.

Furthermore, Ninject aims to keep things simple. Most of other frameworks are complicated and heavyweight, and it needs user to add several assembly dependencies to project.

Third, Ninject have an extremely powerful form of binding called "contextual binding". Ninject can be aware of its environment, and alter the implementation for a give service during activation.

Features[編輯]

  • Ninject has many advanced features. Ninject is designed in a way to use features, that are often necessary, with ease. You need not know all the advanced features for using the basic.
  • Ninject is developed with only .NET base library. It doesn't use any third party libraries. Thus making the application which uses ninject, to deal with very minimal dependencies.
  • CLR has a light-weight code generation feature which is used by Ninject to make the performance better.
  • Ninject doesn't use any XML configuration files like other dependency injectors.
  • Ninject is component-based-architecture. Which means the software can be customized according to the application and usage.
  • Ninject can also inject different implementations of a service during rum-time. i.e; depending on the context.

History[編輯]

There were many IOC Containers prior to Ninject. Ninject version-1 wasn't the first Dependency Injection container. Ninject version-2 wasn't backward compatible with version-1. Developers wanted something new which doesn't rely on XML configuration files to guide the framework to pull up every component of your application. Ninject version-3 uses " embedded domain-specific language" to declare the bindings.

Getting Started[編輯]

Download[編輯]

Ninject can be easily downloaded from Ninject[2]

Souce code of Active Job available on GitHub.[3]

Hello Ninject![4][編輯]

Once we have Ninject DLLs in our drive, the first step is to add a reference to Ninject.dll in our library directory.

Add a new class to our project and call it SalutationService:

class SalutationService
{
    public void SayHello()
    {
        Console.WriteLine("Hello Ninject!")
    }
}

Add using Ninject to the using section of Program.cs. Add the following lines to Main method:

using (var kernel = new Ninject.StandardKernel())
{
    var service = kernel.Get<SalutationService>();
    service.SayHello();
}

There shows how Ninject works in the simple way. We don't need to add any configuration or annotation. Ninject automatically inject in the previous example and print the "Hello Ninject!" for us.

For the detail at the Main method here, firstly, we created a kernel object by instantiating StandardKernel. Kernel is the start point of creating dependency graph, and StandardKernel is the default implementation of such an object. In the example, the graph only consists of one type, SalutationService. We didn't call the constructor of SalutationService in the Main method. Instead, our container(kernel) do it automatically. Get method returned an instance of the given type we required. The Get method was provided with the root type(SalutationService) of our dependency graph and returned the graph object.

Dependency Injection With Ninject[3][編輯]

The most amazing part for Ninject is don't need to spend time on doing the "busy work" of creating and connecting objects by hand.

How Ninject constructs types[編輯]

Ninjects calls one of the constructors on our types, just like we would do Dependency Injection by Hand. When asked to instantiate an object, Ninject will look at the type's of available public constructors and pick the one with the most parameters it knows how to resolve. This means that if we want to resolve and have dependencies injected anything to the service class, Ninject is able to instantiate our objects.

Examples[5][編輯]

Defined the ITaxCalculator interface and a trivial implementation TaxCalculator as follows:

decimal CalculateTax(decimal gross);
public class TaxCalculator : ITaxCalculator
{
    private readonly decimal _rate;
 
    public TaxCalculator(decimal rate)             
    {
        _rate = rate;
    }
 
    public decimal CalculateTax(decimal amount)
    {
        return Math.Round(_rate * amount, 2);
    }
}

Now, if one of more classes need to use an ITaxCalculator implementation to fulfill their responsibility, we can say that an implementation of ITaxCalculator is a dependency to them.

using (IKernel kernel = new StandardKernel())
{
    kernel.Bind<ITaxCalculator>()
          .To<TaxCalculator>()
          .WithConstructorArgument("rate", .2M);
 
    var tc = kernel.Get<ITaxCalculator>();
    Assert.Equal(20M, tc.CalculateTax(100M));
}

Through the interface, we instructed the kernel how to bind requests for ITaxCalculator to TaxCalculator class, passing to its constructor a given tax rate. Now, a Sale class models an ongoing transaction. The class depends on a ITaxCalculator to compute the final price of the shopping cart.

public class Sale
{
    private readonly ITaxCalculator taxCalculator;
 
    public Sale(ITaxCalculator taxCalculator)
    {
        this.taxCalculator = taxCalculator;
    }
 
    // more stuff....
 
    public decimal GetTotal()
    {
    // use the tax calculator to calculate the total
    }
}

Create the sale based on the preceding example:

kernel.Bind<ITaxCalculator>()
          .To<TaxCalculator>()
          .WithConstructorArgument("rate", .2M);
var sale = new Sale(kernel.Get<ITaxCalculator>());>

Or let Ninject to find out how a Sale should be built based on the binding information it received:

kernel.Bind<ITaxCalculator>()
          .To<TaxCalculator>()
          .WithConstructorArgument("rate", .2M);
var sale = kernel.Get<Sale>();

Ninject is able to build a Sale class to take care of fulfilling the dependencies behind the scenes.

External links[編輯]

References[編輯]

  1. ^ Ninject. CodePlex. [2016-09-13]. 
  2. ^ Ninject. 
  3. ^ 3.0 3.1 GitHub. 
  4. ^ 引用錯誤:沒有為名為:0的參考文獻提供內容
  5. ^ Ricciardi, Stefano. Ninject Mini Tutorial.