现在的位置: 首页 > 综合 > 正文

C# 反射工厂模式的实现

2013年01月08日 ⁄ 综合 ⁄ 共 3612字 ⁄ 字号 评论关闭

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace NET.MST.Sixth.ReflectionFactory
{
    /// <summary>
    /// 使用者
    /// </summary>
    class Customer
    {
        static void Main(string[] args)
        {
            //使用者的代码和传统实现一样
            IProduct window = FactoryManager.GetProduct(RoomParts.Window);
            IProduct pillar = FactoryManager.GetProduct(RoomParts.Pillar);
            IProduct roof = FactoryManager.GetProduct(RoomParts.Roof);
            Console.Read();
        }
    }
    /// <summary>
    /// 工厂管理类型
    /// </summary>
    class FactoryManager
    {
        public static IProduct GetProduct(RoomParts part)
        {
            Factory factory = new Factory();
            IProduct product = factory.Produce(part);
            Console.WriteLine("生产了一个产品:" +
                product.GetName());
            return product;
        }
    }

    /// <summary>
    /// 屋子产品的零件
    /// </summary>
    enum RoomParts
    {
        Roof,
        Window,
        Pillar
    }
    /// <summary>
    /// 这个特性用来附加在产品类型之上,
    /// 来标注该类型代码哪个产品,方便反射使用
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    class ProductAttribute : Attribute
    {
        //标注零件的成员
        private RoomParts _myRoomPart;

        public ProductAttribute(RoomParts part)
        {
            _myRoomPart = part;
        }
        public RoomParts RoomPart
        {
            get
            {
                return _myRoomPart;
            }
        }
    }
    /// <summary>
    /// 这个特性用来附加在产品接口之上
    /// 来标注一共实现了多少产品零件,方便反射使用
    /// </summary>
    [AttributeUsage(AttributeTargets.Interface)]
    class ProductListAttribute : Attribute
    {
        private Type[] _myList;

        public ProductListAttribute(Type[] Products)
        {
            _myList = Products;
        }
        public Type[] ProductList
        {
            get
            {
                return _myList;
            }
        }
    }

    #region 产品类族
    /// <summary>
    /// 产品零件接口,
    /// 需要添加所有实现该接口的列表
    /// </summary>
    [ProductList(new Type[]{
                typeof(Roof),
                typeof(Window),
                typeof(Pillar)})]
    interface IProduct
    {
        String GetName();
    }
    /// <summary>
    /// 屋顶类型
    /// </summary>
    [ProductAttribute(RoomParts.Roof)]
    class Roof : IProduct
    {
        public String GetName()
        {
            return "屋顶";
        }
    }
    /// <summary>
    /// 窗户类型
    /// </summary>
    [Product(RoomParts.Window)]
    class Window : IProduct
    {
        public String GetName()
        {
            return "窗户";
        }
    }
    /// <summary>
    /// 柱子类型
    /// </summary>
    [ProductAttribute(RoomParts.Pillar)]
    class Pillar : IProduct
    {
        public String GetName()
        {
            return "柱子";
        }
    }
    #endregion

    #region 工厂类
    /// <summary>
    /// 工厂类型,这里不再需要一个类族,
    /// 而只需要一个工厂类型
    /// </summary>
    class Factory
    {
        public IProduct Produce(RoomParts part)
        {
            //通过反射,从IProduct 接口中获得属性,
            //从而获得所有的产品零件列表
            ProductListAttribute Attr = (ProductListAttribute)
                    Attribute.GetCustomAttribute(typeof(IProduct),
                            typeof(ProductListAttribute));

            //遍历所有的实现产品零件类型
            foreach (Type type in Attr.ProductList)
            {
                //利用反射查找其属性
                ProductAttribute pa = (ProductAttribute)
                                    Attribute.GetCustomAttribute(
                                    type, typeof(ProductAttribute));
                //确定是否是需要的零件
                if (pa.RoomPart == part)
                {
                    //再一次利用反射
                    //创建产品零件类型
                    Object product = Assembly.GetExecutingAssembly().
                        CreateInstance(type.FullName);
                    return product as IProduct;
                }
            }
            //不应该到达这里
            return null;
        }
    }
    #endregion
}

抱歉!评论已关闭.