IOC应用之 Ninject

时间:2021-03-16 19:52:18

什么是Ninject

Ninject是一套.Net平台下的高效,超轻量级的依赖注入库。它可以帮助你实现应用程序的松耦合,高内聚,同时也能很灵活的把它们进行组合在一起。借助与Ninject的帮助,代码的使用,复用,测试和修改变得异常的简单。

为什么使用Ninject

既然在.Net平台下依赖注入已经很普遍,同时也已经有了好几个依赖注入库。为什么我们还要另外编写一套呢?

首先,目前其他框架依赖于XML配置文件,通过配置文件去引导框架的组件的工作,这将带来以下不足:

1.        配置文件会很长,并且很冗余,因为你必须为每一个类型重复性的去写他得描述信息;

2.        一个简单的配置错误就会导致整个工程的瘫痪;

第二点,其他框架是很庞大的类库,那么意味着库还依赖于其他库,这对于小型的系统而言就会产生“框架膨胀”的问题。

第三点,Ninject提出了一种异常强大并且灵活的“上下文绑定”技术。类比简单的字符串绑定,Ninject能感知环境,并且能根据不同的运行环境实现不同的接口。

事例

public interface IWeapon
{
void Attack(string target);
}
public class Sword : IWeapon
{
public void Attack(string target)
{
Console.WriteLine("Attack " + target + " by sword");
}
}
public class Knife : IWeapon
{
public void Attack(string target)
{
Console.WriteLine("Attack " + target + " by knife");
}
}

类型绑定

public class WeaponModule : NinjectModule
{
public override void Load()
{
this.Bind().To();
}
}

使用

static void Main(string[] args)
{
IKernel kernel = new StandardKernel(new WeaponModule());
IWeapon weapon = kernel.Get();
weapon.Attack("小明");
Console.ReadKey();
}

 对象作用域

作用域

绑定方法

说明

Transient

.InTransientScope()

每次调用创建新实例。

Singleton

.InSingletonScope()

单例,仅创建一个实例。

Thread

.InThreadScope()

每一个线程创建一个实例。

Request

.InRequestScope()

每当Web请求发起时创建一个实例,结束请求时释放实例

复杂绑定处理

this.Bind().To().Named("Sword");
this.Bind().To().Named("Knife");
IWeapon weapon1 = kernel.Get("Sword");
IWeapon weapon2 = kernel.Get("Knife");

动态载入模块

IKernel kernel = new StandardKernel();
kernel.Load(AppDomain.CurrentDomain.GetAssemblies());

扩展Asp.Net MVC

// 重写ControllerFactory
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel _kernel = new StandardKernel(new PersonModule());
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
if (controllerType == null) return null;
return (IController)_kernel.Get(controllerType);
}
} // 重新设置ControllerFactory
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// 设置ControllerFactory为NinjectControllerFactory
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}