【问题标题】:C# Constructor Pattern based on class methods基于类方法的 C# 构造函数模式
【发布时间】:2020-03-06 19:11:54
【问题描述】:

我需要创建一个考虑到当前程序集的系统并基于该程序集执行 x 操作(反射)。

主要思想是为方法分配属性,因此未来几年不需要大量维护,但也会开发新的类以具有新的属性/方法的类似情况。

主要问题是我对不同的类有不同的参数(我是从抽象类继承的)

基类:

public abstract class HelpItem : INotifyPropertyChanged
{
    public HelpItem()
    {

    }

    string group;
    SvgImage image;
    string description;
    string help;
    string name;

    public string Name
    {
        get { return name; }
        set
        {
            name = value;
        }
    }


    public string Help
    {
        get { return help; }
        set
        {
            if (help == value)
                return;
            help = value;
            OnPropertyChanged(this, new PropertyChangedEventArgs(nameof(Help)));
        }
    }


    public string Group
    {
        get { return group; }
        set
        {
            if (group == value)
                return;
            group = value;
            OnPropertyChanged(this, new PropertyChangedEventArgs(nameof(Group)));
        }
    }


    public string Description
    {
        get { return description; }
        set
        {
            if (description == value)
                return;
            description = value;
            OnPropertyChanged(this, new PropertyChangedEventArgs(nameof(Description)));
        }
    }


    public SvgImage Image
    {
        get { return image; }
        set
        {
            if (image == value)
                return;
            image = value;
            OnPropertyChanged(this, new PropertyChangedEventArgs(nameof(Image)));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(sender, e);
    }

    [Action("&Open")]
    public abstract void Run();

    public static IList<HelpAttribute> GetHelpItems()
    {
        return GetHelpItems<HelpItem>();
    }


}

这个类的用法是:

    public class PfdHelpItem : HelpItem
{
    public PfdHelpItem(System.IO.MemoryStream stream, DevExpress.XtraBars.Docking2010.DocumentManager docManager)
    {
        DocManager = docManager;
        Stream = stream;
    }

    public MemoryStream Stream { get; set; }
    public DocumentManager DocManager { get; set; }

    bool isExternal;

    public bool IsExternal
    {
        get { return isExternal; }
        set
        {
            if (isExternal == value)
                return;
            isExternal = value;
            OnPropertyChanged(this, new PropertyChangedEventArgs(nameof(IsExternal)));
        }
    }

    public override void Run()
    {
        ...
    }

    [Action("Open &externally")]
    public void RunExternal()
    {
        ...
    }

    [Action("&Save as...")]
    public void SaveAs()
    {
       ...
    }
}

属性类:

public abstract class HelpAttribute : Attribute
{
    public HelpAttribute(string name, string title, string description)
    {
        Description = description;
        Title = title;
        Name = name;
    }

    public string Name { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
}

然后我还有其他子类:

public class PdfHelpAttribute : HelpAttribute
{
    public PdfHelpAttribute(string name, string title, string description) 
        : base(name, title, description)
    {

    }
}

那么这个属性的使用:

    /// <summary>
    ///   Looks up a localized resource of type System.Byte[].
    /// </summary>
    [Misc.Help.PdfHelp("MyFileName", "Title", "Desc")]
    internal static byte[] MyPdfFile{
        get {
            object obj = ResourceManager.GetObject("MyPdfFile", resourceCulture);
            return ((byte[])(obj));
        }
    }

因此如示例所示,在这种情况下,它将从资源中获取 PDF 文件并对其进行处理、打开、保存等。

还有一个OnlineHelp类,里面填充了url地址,还有其他的动作。

想法是从反射中获取所有HelpItems并根据需要显示。

是否有已知的模式可以处理这种情况?

提前致谢!

【问题讨论】:

    标签: c# design-patterns constructor factory builder


    【解决方案1】:

    您可以使用的一种模式如下:

    1. 为您要查找的所需功能定义一个接口。
    2. 在抽象基类中实现接口。
    3. 创建一个清单类。
    4. 使用一组程序集初始化库存类。该集合可以静态定义,也可以通过循环访问应用程序域中的可用程序集来动态定义。
    5. 循环遍历程序集中的所有类型。
    6. 循环遍历这些类型(和基类型)中的所有接口
    7. 使用适当的结构构建可用于实现不同接口的类型清单。
    8. 添加一个方法,以便在需要时在运行时获取可用类型。

    使用接口作为公分母的原因是,它们通常比所有可用类型少得多,从而可以更快地创建库存并消耗更少的内存。

    示例:查看Waher.Runtime.Inventory nuget 的静态Types 类中的InitializeGetTypesImplementingInterface 方法:

    https://github.com/PeterWaher/IoTGateway/blob/master/Runtime/Waher.Runtime.Inventory/Types.cs

    可以与TypesLoader类结合,在启动时动态加载所有可用的程序集:

    https://github.com/PeterWaher/IoTGateway/blob/master/Runtime/Waher.Runtime.Inventory.Loader/TypesLoader.cs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      • 2014-03-13
      • 2015-08-18
      • 2011-12-26
      • 2013-03-24
      相关资源
      最近更新 更多