当前位置:编程学习 > asp >>

Pro ASP.NET MVC 3 Framework学习笔记之八

 

本次的笔记分为三个部分:Ninject(依赖注入容器,前面有介绍的,如果你第一次路过这里,可以先看下我前面的笔记),NUnit(单元测试工具),Moq(用来模拟在单元测试中的接口实现).今天我做的笔记是关于第一部分:Ninject.

 

如果你对依赖注入(DI)没有任何的了解,你可以看看我前面的笔记或者在网上搜索相关的资料进行了解。下面通过一个实例来介绍Ninject的使用,首先我们需要猛击这里下载相关的DLL。我们仍然用到的前面的Product,实现技术所有Product的总价值。下面通过几个步骤来具体的介绍:

 

1.创建一个Console Application,如果你不介意,我们暂且给它命名为NinjectDemo.接下来我们创建一个Product类,如下所示:

 

namespace NinjectDemo

{

    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; }

    }

}

 

接着创建一个接口IValueCalculator,如下所示:

 

namespace NinjectDemo

{

    public inte易做图ce IValueCalculator

    {

        decimal ValueProducts(params Product[] products);

    }

}

 

接着创建一个接口实现,如下所示:

 

namespace NinjectDemo

{

    public class LinqValueCalculator:IValueCalculator

    {

        public decimal ValueProducts(params Product[] products)

        {

            return products.Sum(p => p.Price);

        }

    }

}

 

这里我们计算Products的总价用了LINQ的扩展方法(关于扩展方法在前面的笔记有介绍),当然这里你完全可以自己遍历Products求和并返回一个Decimal类型的值。下面我们创建一个类用来实现依赖注入。ShoppingCart.cs如下所示:

 

    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;

        }

    }

 

2.这里用到的依赖注入就是我们前面笔记里面的介绍的一种Constructor Injection(构造器注入),通过接口实现的实例作为参数传递给ShoppingCart的构造器来实现ShoppingCart与LinqValueCalculator(IValueCalculator接口实现)的解耦。下面的图很好的阐释了这几个类或接口直接的关系,如下所示:

\

 

 

呵呵,其实解耦的操作,按我自己的理解就是达到在两个耦合的对象之间引入一个"第三者",这样我们目的就达到了。当然在程序里面我常常需要这样的"第三者",现实的生活可不要这样,呵呵。这里的比方不是很恰当哈,大家就不要深究了。这里的ShoppingCart与LinqValueCalculator都依赖于IValueCalculator,但是彼此之间并没有直接的联系,甚至不知道彼此的存在。我可以改变LinqValueCalculator的实现,或者干脆用其他的方式来实现IValueCalculator接口,而不会让ShoppingCart有任何察觉,因为现在的它已经不在那么聪明了,呵呵。

 

3.从上面的几个类和接口之间的关系图我们可以发现,ShoppingCart,IValueCalculator,LinqValueCalculator这三个类型都跟Product有直接的联系。我们并不用担心,因为这里的Product等效于Domain Model Type(领域模型类型),并且我期望这样的类跟应用程序的其他部分发生强耦合。当然如果我们不是为了创建MVC程序,我们可能会有不同的看法,或许也会为Product采取解耦操作。

 

4.我们的目标就是要创建ShoppingCart的实例并且以IValueCalculator实现作为构造器参数的方式来注入。这正好是Ninject(DI容器)为我们充当的角色,在我们使用Ninject之前,我先引入Ninject.dll,并且查看一些我们项目的属性确定一下我们的Target Framework是. NET Framework 4,如果是.NET Framework 4 Client Profile,在后面编译时会报错提示没有Ninject命名空间,原因是Client Profile会忽略Ninject.dll。

 

5.关于Ninject的使用,我们可以通过下面的代码(Console Application的Program.cs).如下所示:

 

        static void Main(string[] args)

        {

 IKernel ninjectKernel = new StandardKernel();

 ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();

            //获取接口实现

            IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>();

 

            //创建ShoppingCart的实例并注入依赖

            ShoppingCart cart = new ShoppingCart(calcImpl);

 

            //执行

            Console.WriteLine("Tatol:{0:c}", cart.CalculateStockValue());

 

        }

 

接下来我们对加粗的代码进行介绍,使用Ninject,我们首先创建一个IKernel对象,通过这个对象来与Ninject交互。一旦我们创建了IKernel对象后,接下需要通过Ninject做两个操作。第一,绑定我们要创建的接口类型,在这里就是要告诉Ninject,当收到接口实现的请求时,为我们创建一个LinqValueCalculator的实例并返回给我们。这里我们使用的是在IKernel里面定义的Bind<T>()...To<T>()方法。正如代码:ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();这样

补充:Web开发 , ASP.Net ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,