首页 > 代码库 > .Net实战之反射外卖计费

.Net实战之反射外卖计费

场景

  叫外卖支付,可以有以下优惠:

1、  满30元减12

2、  是会员减配送费,比如5元

3、  优惠券

….

  问题? 如何在不改代码的情况下更灵活的去控制优惠的变化???

  有些代码与实际业务可能不符合,旨在体验反射的用处

   public interface IDiscount    {        /// <summary>        /// 优惠名称        /// </summary>        string Name { get; }                /// <summary>        /// 金额        /// </summary>        /// <param name="money"></param>        /// <returns></returns>        double CalcMoney(double totalMoney);    }

--代金券

namespace CashLib{    /// <summary>    /// 代金券    /// </summary>    public class CashDiscount:IDiscount    {        public string Name        {            get { return "代金券:兔子粮票2元,可抵扣2元"; }        }        public double CalcMoney(double totalMoney)        {            return totalMoney - 2;        }    }}

--会员

namespace MembeLib{    /// <summary>    /// 会员    /// </summary>    public class MemberDiscount:IDiscount    {         public string Name        {            get { return "会员免5元配送费"; }        }        public double CalcMoney(double totalMoney)        {            return totalMoney - 5;        }    }}

--满金额减免

namespace MinusLib{    /// <summary>    /// 足价减金额    /// </summary>    public class MinusDiscount : IDiscount    {        public string Name        {            get { return "满30减12元"; }        }        public double CalcMoney(double totalMoney)        {            return totalMoney - 12;        }    }}

--读取优惠策略的程序集,动态创建类的对象并调用类的成员

    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        Dictionary<string, object> dict = new Dictionary<string, object>();        private void Form1_Load(object sender, EventArgs e)        {            string dllPath = AppDomain.CurrentDomain.BaseDirectory + "DiscountLib/";            string[] assFiles = System.IO.Directory.GetFiles(dllPath, "*.dll");            foreach (var dllItem in assFiles)            {                Assembly ass = Assembly.LoadFrom(dllItem);                foreach (Type type in ass.GetTypes())                {                    if (typeof(IDiscount).IsAssignableFrom(type))                    {                        object instanceDiscount = ass.CreateInstance(type.FullName);                        PropertyInfo propDiscountName = type.GetProperty("Name");                        string discountName = propDiscountName.GetValue(instanceDiscount).ToString();                        this.listBox1.Items.Add(discountName);                        dict.Add(discountName, instanceDiscount);                    }                }            }        }        private void button1_Click(object sender, EventArgs e)        {            CustomerOrder cusOrder = new CustomerOrder("张三", 35);            foreach (string item in this.listBox1.SelectedItems)            {                cusOrder.AddDiscount(dict[item] as IDiscount);            }            cusOrder.UseDiscount();        }    }

--存放优惠券程序集

技术分享

--结果

--无优惠券

技术分享

--选择了代金券粮票

技术分享

--会员+代金券

技术分享

--全选

技术分享

 --有新的优惠券,只需将新的dll放在Debug\DiscountLib文件夹中,系统加载时候会自动加载全部优惠

 --去掉或修改某个优惠,只需直接修改相应代码或删除某程序集,不影响其他优惠业务。。。。

 --反射结合抽象类或接口,将会很大程度的提高了程序的拓展性

 --时间仓促,写的不是很细,更多细节以及反射的操作见下篇,保证这辈子永远都会熟悉使用反射,如有兴趣扫描加入程序员工作聊(必须是程序员)的微信讨论组或QQ群

--代码在QQ群

技术分享 

.Net实战之反射外卖计费