依赖注入之Ninject框架

/*

之前写的代码现在交给另一个同学重构了,我果然比较弱,呜呜呜。然后现在被派去看asp .net mvc。

作为一个c#零基础的人,真是淡淡的忧伤啊。

以上纯属我个人碎碎念,请无视之。

文章转自http://blog.csdn.net/leesmn/article/details/6992212

基本是Pro asp.net mvc 3 Framework这本书里面的东西翻译过来的,本身东西就比较绕,看英文理解难度大。

*/

这次要介绍的是一个非常不错的DI(即依赖注入)框架,就是Ninject,通过使用此框架,可以非常方便地实现DI。不过在介绍此框架之前,先让我们再来看看到底为什么要使用依赖注入和其具体实现吧。

请大家先看以下代码,我们先创建最基本的产品类,然后添加一个价格计算接口和一个实现此接口的类:

    //产品类
    public class Product
    {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string Category { set; get; }
    }
    //价格计算接口
    public interface IValueCalculator
    {
        decimal ValueProducts(params Product[] products);
    }
    //实现价格计算接口
    public class LinqValueCalculator : IValueCalculator
    {
        public decimal ValueProducts(params Product[] products)
        {
            return products.Sum(p => p.Price);
        }
    } 

接下来再创建购物车类,然后将以上接口添加进去:

  public class ShoppingCart
    {
        private IValueCalculator calculator;

        public ShoppingCart(IValueCalculator calcParam)
        {
            calculator = calcParam;
        }

        public decimal CalculateStockValue()
        {
            // 定义和设置产品信息
            Product[] products = 
            { 
                        new Product() {  Name = "Kayak", Price  = 275M}, 
                        new Product() {  Name = "Lifejacket",  Price = 48.95M},  
                        new Product() {  Name = "Soccer ball",  Price = 19.50M}, 
                        new Product() {  Name = "Stadium", Price  = 79500M} 
            };
            // 计算总价格  
            decimal totalValue = calculator.ValueProducts(products);

            // 返回计算结果  
            return totalValue;
        }
    }

 

从以上代码可看出,ShoppingCart和LinqValueCalculator都依赖于IValueCalculator接口,但ShoppingCart和LinqValueCalculator之间并没有直接关系,甚至ShoppingCart并不知道LinqValueCalculator的存在,这样的好处也显而易见,就是LinqValueCalculator可以随时更换而不会影响到ShoppingCart里的代码,因此也达到了松耦合的效果了。

以下是上面几个类的关系图:

OK,现在看看如何结合Ninject来使用以上代码。首先要为你的项目添加Ninject引用,在项目名称里点击右键,然后选择“Add PackageLibrary Reference”,然后只需在搜索框里输入 ninject ,这时就可看到下面的选择列表里出现了 Ninject的项目了,直接选择安装即可

 

为了方便演示,只需创建一个控制台项目即可。要使用Ninject,可直接调用IKernel接口,代码如下:

    class Program
    {
        static void Main(string[] args) 
        { 
            IKernel ninjectKernel = new  StandardKernel(); 
            //绑定接口到实现类里
            ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator<(); 
        }
    }

以上代码将接口与实现类绑定起来了,然后再添加以下代码以实现ShoppingCart类:

   // 获取实现的接口
  IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>(); 
  // 创建实例注入到 ShoppingCart 
  ShoppingCart cart = new  ShoppingCart(calcImpl); 
  // 执行计算功能以输出结果
  Console.WriteLine("Total: {0:c}", cart.CalculateStockValue());

可能大家会感觉这样使用还不如直接调用来得方便啊,如果不使用 Ninject ,我们只需直接使用:

 ShoppingCart cart =  new ShoppingCart(new LinqValueCalculator());

这样就可以了,不是方便很多吗?为什么还要用Ninject写这么多代码呢?
嗯,以上其实只是一个最简单的为了演示的代码,如果随着复杂的多层接口的注入增加的话,就可以马上体现出Ninject的效率和好处了!

请继续看以下代码,我们再添加一个新的折扣接口:

 //添加折扣接口
    public interface IDiscountHelper
    {
        decimal ApplyDiscount(decimal totalParam);
    }

    //实现不同的折扣
    public class DefaultDiscountHelper : IDiscountHelper
    {

        public decimal ApplyDiscount(decimal totalParam)
        {
            return (totalParam - (10m / 100m * totalParam));
        }
    }

    //为之前的价格功能里添加折扣功能,实现折扣接口
    public class LinqValueCalculator : IValueCalculator
    {
        private IDiscountHelper discounter;

        public LinqValueCalculator(IDiscountHelper discountParam)
        {
            discounter = discountParam;
        }

        public decimal ValueProducts(params Product[] products)
        {
            return discounter.ApplyDiscount(products.Sum(p => p.Price));
        }
    }

现在我们又多了一层注入的接口了,但使用Ninject的话就非常方便,只需添加多一行代码就可以了:

    ... 
  IKernel ninjectKernel = new StandardKernel();  
  
  ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>(); 
  //这是为新接口添加的,其他代码均不需改动
  ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>(); 
  
  // 获取实现的接口  
  IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>(); 
  ShoppingCart cart = new  ShoppingCart(calcImpl); 
  Console.WriteLine("Total: {0:c}", cart.CalculateStockValue()); 
  ...

随着代码接口的复杂性增多,就可以体现出Ninject的好处了 

 

ASP.NET MVC中应用:

namespace NinjectDemo.Infrastructure
{
    public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel ninjectKernel;
        public NinjectControllerFactory()
        {
            ninjectKernel = new StandardKernel();
            AddBindings();
        }
        protected override IController GetControllerInstance(RequestContext requestContext,
        Type controllerType)
        {
            return controllerType == null
            ? null
            : (IController)ninjectKernel.Get(controllerType);
        }
        private void AddBindings()
        {
            // put additional bindings here
            ninjectKernel.Bind<IProductRepository>().To<FakeProductRepository>();
        }
    }
}

protected void Application_Start() 
{
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值