Ioc系列之Ninject高级使用与webapi调用(普通版)

我有一组产品 我要获取总价,一般正常情况都是使用设计模式之策略模式来搞定,非常简单。

但我们这里要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

posted on 2013-03-04 18:59  ~紫鱼~  阅读(1737)  评论(2编辑  收藏  举报