in rd-net/RdFramework/Base/RdBindableBase.cs [250:296]
public T GetOrCreateExtension<T>(string name, Func<T> create) where T : class =>
GetOrCreateExtension(name, false, create);
internal T GetOrCreateHighPriorityExtension<T>(string name, Func<T> create) where T : class =>
GetOrCreateExtension(name, true, create);
private T GetOrCreateExtension<T>(string name, bool highPriorityExtension, Func<T> create) where T:class
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (create == null) throw new ArgumentNullException(nameof(create));
lock (myExtensions)
{
T res;
if (myExtensions.TryGetValue(name, out var existing))
{
var val = existing.NotNull("Found null value for key: '{0}'", name) as T;
Assertion.Require(val != null, "Found bad value for key '{0}'. Expected type: '{1}', actual:'{2}", name, typeof(T).FullName, existing.GetType().FullName);
res = val;
}
else
{
res = create().NotNull("'Create' result must not be null");
myExtensions[name] = res;
if (res is IRdBindable bindable)
{
BindableChildren.Insert(highPriorityExtension ? 0 : BindableChildren.Count, new KeyValuePair<string, object>(name, bindable));
var proto = TryGetProto();
if (proto == null)
return res;
var bindLifetime = myBindLifetime;
if (bindLifetime.IsAlive)
{
if (bindable.RdId == RdId.Nil)
bindable.Identify(proto.Identities, RdId.Mix("." + name));
bindable.PreBind(bindLifetime, this, name);
bindable.Bind();
}
}
}
return res;
}
}