.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群

时间: 2024-08-25 15:44:19

.Net实战之反射外卖计费的相关文章

.Net实战之反射相关类之间的人体经络关系

--1.类的部分组成成员 --2.巧记成员之间的关系 [MyTableAttribute("T_UserInfo")] public class UserInfo : Person, UserService { private int _age2; private int _age; [DisplayName("年龄")] public int Age { get { return _age; } set { _age = value; } } [DisplayNa

Vue.js高仿饿了么外卖App 前端框架Vue.js 1.0升级2.0

课程目录:第1章 课程简介介绍课程的学习目标和学习内容.第2章 Vuejs介绍从前端开发趋势分析开始,引入 MVVM 开发框架和 Vue.js,接着对比流行框架Angular 和 React,最后详细介绍 Vue.js 的核心思想-数据驱动和组件化.第3章 Vue-cli 开启 Vuejs 项目介绍 Vue 项目的脚手架,如何安装,对脚手架生成的目录文件做介绍,介绍 Vue 组件的编写方法,最后运行 demo 项目并介绍 webpack 构建脚本来说明 demo 的运行原理.第4章 项目实战-准

Vue.js 高仿饿了么外卖APP

第1章 课程简介介绍课程的学习目标和学习内容.1-1 课程简介1-2 课程安排 第2章 Vuejs介绍从前端开发趋势分析开始,引入 MVVM 开发框架和 Vue.js,接着对比流行框架Angular 和 React,最后详细介绍 Vue.js 的核心思想-数据驱动和组件化.2-1 Vuejs介绍-近年来前端开发趋势2-2 Vuejs介绍-MVVM框架2-3 Vuejs介绍-什么是Vuejs及Vuejs生态2-4 Vuejs介绍-对比Angular.React2-5 Vuejs介绍-Vuejs核心

征服大前端第二季(Node.js、Angular 4、Express 4、Keystone 4)

征服大前端第二季(Node.js.Angular 4.Express 4.Keystone 4.MongoDB.MySQL)网盘地址:https://pan.baidu.com/s/1RFi_3H9vLXM3-2Glv4SGvA 密码: vhut备用地址(腾讯微云):https://share.weiyun.com/5JkpoZb 密码:dqn36n Hybrid App(混合模式移动应用)是指介于web-app.native-app这两者之间的app,兼具"Native App良好用户交互体验

C#反射基础知识和实战应用

首先来说一下什么是反射? 反射提供了封装程序集.模块和类型的对象(Type类型) 可以使用反射动态的创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后,可以调用类型的方法或访问其字段和属性 . 总之,有了反射,以前很多实现不了的功能都可以实现. 下面先来写一个小例子,体验一下反射是怎么一回事: 打开VS2010,新建一个控制台应用程序,在program.cs里面写代码 首先引入命名空间: using System.Reflection; 下如下代码: PropertyInfo l

Java反射实战

一.背景 最近的项目中需要使用到Java 反射的知识,以前不怎么了解,也基本没怎么用过,抽出一片时间,来具体学习和实战下Java的反射!拿来和大家分享以及记录方便以后学习! 二.反射相关概念解析 1.Class类 Class类:Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class. 如何得到各个类的字节码即Class类呢? [1].类名.class:直接通过类.class获得. [2].对象.getClass():通过对象调用其getClass方法获得. [3]

黑马2018年最新kotlin项目实战视频 (手机影音、即时通讯、黑马外卖、坦克大战等)

├─1.kotlin简介和学习方法│ 01_kotlin课程简介_01.mp4│ 02_kotlin学习方法_01.mp4│ 03_kotlin选好教练车_01.mp4│ 03_kotlin选好教练车_02.mp4│ 04_kotlin你好世界_01.mp4│ 05_kotlin变量与输出_01.mp4│ 05_kotlin变量与输出_02.mp4│ ├─10.类,对象和接口(三)│ 38_kotlin面向对象-抽象类和接口_01.mp4│ 38_kotlin面向对象-抽象类和接口_02.mp4

程序集加载与反射(二):实战篇

目录: 上篇:http://www.cnblogs.com/sunchong/p/4550476.html Demo 一.Demo 下面这个Demo,使用了策略模式模仿了一下插件机制.我们举个一邮件发送的例子: 1.一个策略类库:Strategy,里面定义了邮件需要实现的接口:IEmailStrategy. using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys

(转)反射发送实战(-)InvokeMember

反射是.net中的高级功能之一,利用反射可以实现许多以前看来匪夷所思的功能,下面是我看了<Programming C#>(O'Reilly)之后对于反射的一点实践,本想直接做个应用程序来说明问题,但苦于工作繁忙并考虑到以简单为主,故先对反射发送(reflection emit)的使用做一些介绍.文章最后再给出一个实例. 下面的程序在运行时生成了一个Test.cs文件,并调用csc编译成Test.dll文件,然后利用Type.InvokeMember()方法调用其中的SayHello()方法,然