我有一组产品 我要获取总价,一般正常情况都是使用设计模式之策略模式来搞定,非常简单。
但我们这里要Ioc工具-Ninject,那我们就得写很多接口了。
/// <summary> /// 正常价格 /// </summary> public interface INormal { /// <summary> /// 返回价格总数 /// </summary> /// <param name="products"></param> /// <returns></returns> decimal TotalSum(); /// <summary> /// 总数 /// </summary> decimal Total { get; set; } }
/// <summary> /// 商品打折 /// </summary> public interface IDiscount { /// <summary> /// 对商品进行打折 /// </summary> /// <param name="Discount"></param> /// <param name="products"></param> /// <returns></returns> decimal DisCountTotalSum(); decimal Discount { get; set; } /// <summary> /// 总数 /// </summary> decimal Total { get; set; } }
/// <summary> /// 买多少减多少 /// </summary> public interface IReturn { decimal ReturnTotalSum(); decimal ReturnCash { get; set; } /// <summary> /// 总数 /// </summary> decimal Total { get; set; } }
很多同学问我,为什么要用属性来做。我之所以这样用就是为了让同学们更加了解Ninject 带构函数,带属性注入到容器里。
using Ninject; using Strategy; namespace Service { public class NinjectBinder { private IKernel kernel; /// <summary> /// 其实这里应该在MVC里面注册的 /// </summary> /// <param name="kernel"></param> /// <param name="total"></param> /// <param name="para"></param> public NinjectBinder(IKernel kernel,decimal total,decimal para) { this.kernel = kernel; this.kernel.Bind<INormal>().To<Service>().WithPropertyValue("Total", total); this.kernel.Bind<IDiscount>().To<Service>().WithPropertyValue("Total", total).WithPropertyValue("Discount", para); this.kernel.Bind<IReturn>().To<Service>().WithPropertyValue("Total", total).WithPropertyValue("ReturnCash", para); //下面是Ninject 常用2个带属性和构造函数 注入容器的办法 //WithPropertyValue 是指Ninject 属性(get set) 获取注入 //WithConstructorArgument 是Ninject 构造函数 获取注入 } } }
前台采用webapi 方式操作数据:
public static IList<Product> products = new List<Product>() { new Product{Id="1",ProductName="Iphone4s",Price=3788}, new Product{Id="2",ProductName="Ipad3",Price=2788} }; // GET api/values/ public string Get() { var json = JsonConvert.SerializeObject(products); return json; } // GET api/values/5 public string Get(decimal id) { IKernel kernel = new StandardKernel(); decimal result = products.Sum(p => p.Price); decimal para; if (id > 0 && id < 100) { para = id / 10; } else para = id; NinjectBinder binder = new NinjectBinder(kernel, result, para);//这里应该到全局里注册的 var sum = ""; switch (id.ToString()) //这里使用了固定的值 可以采用枚举 和XML配置 来反射做 { case "0": INormal normal = kernel.Get<INormal>(); sum = normal.TotalSum().ToString(); break; case "9": IDiscount discount = kernel.Get<IDiscount>(); sum = discount.DisCountTotalSum().ToString(); break; case "100": IReturn returns = kernel.Get<IReturn>(); sum = returns.ReturnTotalSum().ToString(); break; } return sum.ToString(); }
我这里才用Swtich方式来从容器获取服务类,其实这里应该用MVC的全局注册来做。我下一个版本将写到。目前工作太多了。
从上面代码,我们可以看到Ioc注入工具Ninject 可以很轻松帮我实现多个接口调用,再配合Web api 我们可以很轻松的实现网站的日常需求。
示例代码下载:Ioc_Ninject_Complex.zip