通过包装器传递类元数据

Posted

技术标签:

【中文标题】通过包装器传递类元数据【英文标题】:Passing class metadata through a wrapper 【发布时间】:2016-02-03 16:08:54 【问题描述】:

我想看看是否有办法让包装类在运行时将属性附加到自身,或任何其他方式从包装类继承某些元数据。

我希望这不会太长,但这就是我所拥有的:

首先有一个特定的类表示要发送到设备的命令:

public interface IDeviceCommand

    string Name  get; 
    byte[] ToByteArray();


public class SomeCommand : IDeviceCommand
 ... 

public class SomeOtherCommand : IDeviceCommand
 ... 

可以从应用程序中的各个地方向设备发送命令,但是有些命令比其他命令更重要,所以我还定义了一个标记接口IPriorityCommand,表示应该立即发送该命令:

// this could also be an attribute btw
public interface IPriorityCommand  

然后我的命令调度程序会检查这个:

public void SendCommand(IDeviceCommand command) 

    if (command is IPriorityCommand)
       SendNow(command);
    else
       Enqueue(command);

此外,有时可能需要包装命令以稍微更改其内容,或添加一些其他功能:

public SomeCommandWrapper : IDeviceCommand

     readonly IDeviceCommand _innerCommand;
     public CommandWrapper(IDeviceCommand inner)
      _innerCommand = inner; 

     // acts as a proxy, or changes data in a certian way

但现在我的问题是包装实例不再实现优先级命令。另外,我有几种包装器类型,因此每个包装器都有两个版本是没​​有意义的,只是它们的接口不同。

我也可以使用属性而不是接口,但我不知道如何在运行时设置对象的属性,如果可能的话。

另外一个问题是,其中一些命令包装器是通用的,即定义在一个对IPriorityCommand 一无所知的程序集中。

【问题讨论】:

【参考方案1】:

不使用标记接口 (IPriorityCommand) 在 I-IDeviceCommand 中声明属性,例如 IsHighPriority

由于命令的优先级是在编译时定义的(通过实现 IPriorityCommand),您还可以让 IsHighPriority 属性实现在 SomeCommand 和 SomeOtherCommand 中返回 true 或 false

最后在 SomeCommandWrapper 中,将 IsHighPriority 属性实现为:

public bool IsHighPriority  get  return _innerCommand.IsHighPriority;  

【讨论】:

+1 谢谢,一个问题可能是 IDeviceCommand 在单独的程序集中实现,而我的程序集正在引用它并扩展调度程序。 但是派生的调度器仍然可以访问优先级,因为它是公共的?我做错了什么? 实际上,我可以修改IDeviceCommand,但有些选项是特定于我的上层的,所以我不想将它们放在由其他几个应用程序共享的基础程序集中。但没关系,我可能会做这样的事情。我会稍等一下,看看其他人是否有其他想法,如果我没有得到其他任何东西,我会接受这个作为答案。 没关系。目标是彻底了解您的问题。

以上是关于通过包装器传递类元数据的主要内容,如果未能解决你的问题,请参考以下文章

java 类元数据是不是在堆上?

类元数据Class Metadata

使用 Spring AnnotationUtils 解决代码获取类元数据信息

使用 Spring AnnotationUtils 解决代码获取类元数据信息

使用 proguard / R8 删除数据类元数据

我们可以用类元数据填充下拉列表吗?