20121011P125
创造一个kernel,有两次使用:1、将接口的类型和具体实现接口的类型相绑定绑定,目的是为了告诉Ninject,当他接到一个接口类的请求时,他将会创造一个实现接口类的实例。而且是利用泛型实现的。用法如下
IKernel ninjectKernel = new StandardKernel(); ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
2、使用Ninject的Get方法来创造一个接口的实例,并将其作为注入依赖。最终达到依赖的“宿主”可以调用抽象类的方法。具体如下:
// get the interface implementation IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>(); // create the instance of ShoppingCart and inject the dependency ShoppingCart cart = new ShoppingCart(calcImpl); // perform the calculation and write out the result Console.WriteLine("Total: {0:c}", cart.CalculateStockValue());
上面就简单的使用了Ninject,所有代码如下:
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Ninject; namespace NinjectForTest { 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() { // define the set of products to sum 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} }; // calculate the total value of the products decimal totalValue = calculator.ValueProducts(products); // return the result return totalValue; } } class Program { static void Main(string[] args) { IKernel ninjectKernel = new StandardKernel(); ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>(); // get the interface implementation IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>(); // create the instance of ShoppingCart and inject the dependency ShoppingCart cart = new ShoppingCart(calcImpl); // perform the calculation and write out the result Console.WriteLine("Total: {0:c}", cart.CalculateStockValue()); Console.ReadKey(); } } }
下面开始看一下其他特性。
链式依赖:
上图左边的是右边的一个私有变量
下面只需呀添加一行代码就可以实现打折了:
ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>();
所有的代码如下:
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Ninject; namespace NinjectForTest { 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; } } #region 打折接口——IDiscountHelper以及接口的实现——DefaultDiscountHelper /// <summary> /// 创建 一个打折接口,打9折 /// </summary> /// public interface IDiscountHelper { decimal ApplyDiscount(decimal totalParam); } /// <summary> /// 实现接口 /// </summary> public class DefaultDiscountHelper : IDiscountHelper { public decimal ApplyDiscount(decimal totalParam) { return (totalParam - (10m / 100m * totalParam)); } } #endregion /// <summary> /// /// </summary> public interface IValueCalculator { decimal ValueProducts(params Product[] products); } 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)); } } public class ShoppingCart { private IValueCalculator calculator; public ShoppingCart(IValueCalculator calcParam) { calculator = calcParam; } public decimal CalculateStockValue() { // define the set of products to sum 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} }; // calculate the total value of the products decimal totalValue = calculator.ValueProducts(products); // return the result return totalValue; } } class Program { static void Main(string[] args) { IKernel ninjectKernel = new StandardKernel(); ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>(); ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>(); // get the interface implementation IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>(); //create the instance of ShoppingCart and inject the dependency ShoppingCart cart = new ShoppingCart(calcImpl); //下面的代码同样可以实现 //ShoppingCart cart = new ShoppingCart(new LinqValueCalculator()); // perform the calculation and write out the result Console.WriteLine("Total: {0:c}", cart.CalculateStockValue()); Console.ReadKey(); } } }
除此之外Ninject还可以指定实现抽象类的属性的参数,如我们想在上面传递一个值,用来指定具体打多少折。其中打折代码和下面调用的代码分别如下:
public class DefaultDiscountHelper : IDiscountHelper { public decimal DiscountSize { get; set; } public decimal ApplyDiscount(decimal totalParam) { return (totalParam - (DiscountSize / 100m * totalParam)); } }
ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithPropertyValue("DiscountSize", 50M);
不用更改最高层的就可以轻松的实现了。慢慢觉得设计模式的重要性了。
3、自我绑定与子类绑定
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Ninject; namespace NinjectForTest { 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; } } #region 打折接口——IDiscountHelper以及接口的实现——DefaultDiscountHelper /// <summary> /// 创建 一个打折接口,打9折 /// </summary> /// public interface IDiscountHelper { decimal ApplyDiscount(decimal totalParam); } /// <summary> /// 实现接口 /// </summary> public class DefaultDiscountHelper : IDiscountHelper { public decimal DiscountSize { get; set; } public decimal ApplyDiscount(decimal totalParam) { return (totalParam - (DiscountSize / 100m * totalParam)); } } #endregion #region 计算商品的总价 /// <summary> /// /// </summary> public interface IValueCalculator { decimal ValueProducts(params Product[] products); } 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)); } } #endregion public class LimitShoppingCart : ShoppingCart { public LimitShoppingCart(IValueCalculator calcParam) : base(calcParam) { // nothing to do here } public override decimal CalculateStockValue() { // filter out any items that are over the limit var filteredProducts = products .Where(e => e.Price < ItemLimit); // perform the calculation return calculator.ValueProducts(filteredProducts.ToArray()); } public decimal ItemLimit { get; set; } } public class ShoppingCart { protected IValueCalculator calculator; protected Product[] products; public ShoppingCart(IValueCalculator calcParam) { calculator = calcParam; // define the set of products to sum products = new[] { 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} }; } public virtual decimal CalculateStockValue() { // calculate the total value of the products decimal totalValue = calculator.ValueProducts(products); // return the result return totalValue; } } class Program { static void Main(string[] args) { IKernel ninjectKernel = new StandardKernel(); //接口绑定 ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>(); //链式绑定 //打折 ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithPropertyValue("DiscountSize", 50M); //子绑定 //计算指定价格以下的总价格 ninjectKernel.Bind<ShoppingCart>().To<LimitShoppingCart>().WithPropertyValue("ItemLimit", 200M); //通过自我绑定来创建DI的宿主,如果自我绑定的话 只能放在最下面,其他的绑定才能生效 ShoppingCart cart = ninjectKernel.Get<ShoppingCart>(); // perform the calculation and write out the result Console.WriteLine("Total: {0:c}", cart.CalculateStockValue()); Console.ReadKey(); // ninjectKernel.Bind<IDiscountHelper>().ToSelf().WithPropertyValue("DiscountSize", 50M); } } }
4、在指定条件下利用上面的几种绑定
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Ninject; namespace NinjectForTest { 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; } } #region 打折接口——IDiscountHelper以及接口的实现——DefaultDiscountHelper /// <summary> /// 创建 一个打折接口,打9折 /// </summary> /// public interface IDiscountHelper { decimal ApplyDiscount(decimal totalParam); } /// <summary> /// 实现接口 /// </summary> public class DefaultDiscountHelper : IDiscountHelper { public decimal DiscountSize { get; set; } public decimal ApplyDiscount(decimal totalParam) { return (totalParam - (DiscountSize / 100m * totalParam)); } } #endregion #region 计算商品的总价 /// <summary> /// /// </summary> public interface IValueCalculator { decimal ValueProducts(params Product[] products); } 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)); } } #endregion #region 条件绑定 public class IterativeValueCalculator : IValueCalculator { public decimal ValueProducts(params Product[] products) { decimal totalValue = 0; foreach (Product p in products) { totalValue += p.Price; } return totalValue; } } #endregion public class LimitShoppingCart : ShoppingCart { public LimitShoppingCart(IValueCalculator calcParam) : base(calcParam) { // nothing to do here } public override decimal CalculateStockValue() { // filter out any items that are over the limit var filteredProducts = products .Where(e => e.Price < ItemLimit); // perform the calculation return calculator.ValueProducts(filteredProducts.ToArray()); } public decimal ItemLimit { get; set; } } public class ShoppingCart { protected IValueCalculator calculator; protected Product[] products; public ShoppingCart(IValueCalculator calcParam) { calculator = calcParam; // define the set of products to sum products = new[] { 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} }; } public virtual decimal CalculateStockValue() { // calculate the total value of the products decimal totalValue = calculator.ValueProducts(products); // return the result return totalValue; } } class Program { static void Main(string[] args) { IKernel ninjectKernel = new StandardKernel(); //接口绑定 ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>(); //链式绑定 //打折 ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithPropertyValue("DiscountSize", 50M); //子绑定 //计算指定价格以下的总价格 ninjectKernel.Bind<ShoppingCart>().To<LimitShoppingCart>().WithPropertyValue("ItemLimit", 200M); //当有注入LimitShoppingCart类的时间,才执行绑定到IterativeValueCalculator上面,先执行的是条件 ninjectKernel.Bind<IValueCalculator>() .To<IterativeValueCalculator>() .WhenInjectedInto<LimitShoppingCart>(); //通过自我绑定来创建DI的宿主,如果自我绑定的话 只能放在最下面,其他的绑定才能生效 ShoppingCart cart = ninjectKernel.Get<ShoppingCart>(); Console.WriteLine("Total: {0:c}", cart.CalculateStockValue()); Console.ReadKey(); } } }
5、mvc中的ninject
由于要用到下一章的例子,暂时先不举例子。