可以注入并使用一些字段吗?
在注入方法的时候需要一些额外字段的支持,该怎么操作?
我不太确定你想要额外字段是哪种形式。
如果是元数据意义上的额外成员,那么很遗憾,无法实现,这是任何注入库都在避免实现的功能。btw,这个需求在某些情况下可以使用源生成解决。
如果你只是想通过增加几个变量来影响方法的行为,那么可以使用闭包来实现;如果你希望变量的生命周期关系与一个实际绑定,那么可以通过一个全局字典来实现(小心内存泄漏,同时应避免在unity中使用ConditionalWeakTable)
我想实现类似Auto-Implemented Property的一些功能,我也想过全局字典,如果对static的字段还好说,但如果对每个instance都用字典处理是不是有点复杂?我看到InjectHelper里有注入field的步骤,是否可以做成一些工具开放?
可否通过例子来说明
例如一个属性
string name=>$"{lastName} {firstName}";
我希望它的getter在第一次调用后固化在一个field里,那样需要额外写一个string的field和一个bool去存储是否第一次调用,我觉得这样写一堆参数很影响代码的直观 于是我希望通过注入达到这样的效果:
[Const]string name=>$"{lastName} {firstName}";
将这个属性注成这样:
string name{get{
if(!name_loaded_UID)name_data_UID=$"{lastName} {firstName}";
return name_loaded_UID;
}}
bool name_loaded_UID;
string name_data_UID;
而这需要一个类似于现在InjectionInfo.Create的东西,也许长这样:
public static InjectionInfo CreateField(Type type, string fieldName, Action<FieldInfo> fieldReceiver);
暴露LowLevel接口是可行的方法,这个后面会考虑。
对于这里的具体问题,事实上是cache功能。可以推广到任意有返回值的函数调用,字段取值操作是前者的子集。使用全局缓存表看起来是一个正确的选择,一个ConditionalWeakTable的临时平替可以实现为:
- Key使用一个包含(MemberInfo,实参列表)的元组表示,Value是一个可空缓存值;
- 对于键中的实参,如果是托管类型,需要用弱引用;
- 数据结构上可以采用Bucket形式,访问子列表时,在可控范围内进行垃圾键删除;
- 实参列表中任意一个弱引用为空时,则应视为垃圾键。