in rd-net/RdFramework.Reflection/ReflectionRdActivator.cs [172:273]
private object ReflectionInitInternal(object instance)
{
var typeInfo = instance.GetType().GetTypeInfo();
if (ReflectionSerializerVerifier.HasRdExtAttribute(instance.GetType().GetTypeInfo()))
ReflectionSerializerVerifier.AssertValidRdExt(typeInfo);
foreach (var mi in SerializerReflectionUtil.GetSerializableFields(typeInfo))
{
var currentValue = ReflectionUtil.GetGetter(mi)(instance);
if (currentValue == null)
{
currentValue = ActivateMember(ReflectionUtil.GetReturnType(mi), mi.Name);
var memberSetter = ReflectionUtil.GetSetter(mi);
memberSetter(instance, currentValue);
}
else
{
var implementingType = ReflectionSerializerVerifier.GetImplementingType(ReflectionUtil.GetReturnType(mi).GetTypeInfo());
if (Mode.IsAssertion) Assertion.Assert(currentValue.GetType() == implementingType,
"Bindable field {0} was initialized with incompatible type. Expected type {1}, actual {2}",
mi,
implementingType.ToString(true),
currentValue.GetType().ToString(true));
}
}
// Add RdEndpoint for Impl class (counterpart of Proxy)
var interfaces = typeInfo.GetInterfaces();
bool isProxy = interfaces.Contains(typeof(IProxyTypeMarker));
var rpcInterface = ReflectionSerializerVerifier.GetRpcInterface(typeInfo);
if (!isProxy && rpcInterface != null)
{
var interfaceMethods = ReflectionSerializerVerifier.GetMethodsMap(typeInfo, rpcInterface);
foreach (var interfaceMethod in interfaceMethods)
{
var adapter = myProxyGenerator.CreateAdapter(rpcInterface, interfaceMethod);
var name = ProxyGenerator.ProxyFieldName(interfaceMethod);
var requestType = ProxyGenerator.GetRequstType(interfaceMethod)[0];
EnsureFakeTupleRegistered(requestType);
var responseNonTaskType = ProxyGenerator.GetResponseType(interfaceMethod, unwrapTask: true);
var responseType = ProxyGenerator.GetResponseType(interfaceMethod, unwrapTask: false);
var endPointType = typeof(RdCall<,>).MakeGenericType(requestType, responseNonTaskType);
var endpoint = ActivateGenericMember(name, endPointType.GetTypeInfo()).NotNull();
SetAsync(endpoint);
if (endpoint is RdReactiveBase reactiveBase)
reactiveBase.ValueCanBeNull = true;
if (ProxyGenerator.IsSync(interfaceMethod))
{
var delType = typeof(Func<,,>).MakeGenericType(typeof(Lifetime), requestType, typeof(RdTask<>).MakeGenericType(responseNonTaskType));
var @delegate = adapter.CreateDelegate(delType, instance);
var methodInfo = typeof(ReflectionRdActivator).GetMethod(nameof(SetHandler)).NotNull().MakeGenericMethod(requestType, responseNonTaskType);
methodInfo.Invoke(null, new[] {endpoint, @delegate});
}
else
{
if (responseType == typeof(Task))
{
var delType = typeof(Func<,,>).MakeGenericType(typeof(Lifetime), requestType, typeof(Task));
var @delegate = adapter.CreateDelegate(delType, instance);
var methodInfo = typeof(ReflectionRdActivator).GetMethod(nameof(SetHandlerTaskVoid)).NotNull().MakeGenericMethod(requestType);
methodInfo.Invoke(null, new[] {endpoint, @delegate});
}
else
{
var delType = typeof(Func<,,>).MakeGenericType(typeof(Lifetime), requestType, typeof(Task<>).MakeGenericType(responseNonTaskType));
var @delegate = adapter.CreateDelegate(delType, instance);
var methodInfo = typeof(ReflectionRdActivator).GetMethod(nameof(SetHandlerTask)).NotNull().MakeGenericMethod(requestType, responseNonTaskType);
methodInfo.Invoke(null, new[] {endpoint, @delegate});
}
}
var bindableChildren = ((IReflectionBindable)instance).BindableChildren;
bindableChildren.Add(new KeyValuePair<string, object>(name, endpoint));
}
}
else if (rpcInterface != null)
{
foreach (var interfaceMethod in rpcInterface.GetMethods())
{
var requestType = ProxyGenerator.GetRequstType(interfaceMethod)[0];
EnsureFakeTupleRegistered(requestType);
}
}
// Allow initialize to setup bindings to composite properties.
if (instance is IReflectionBindable reflectionBindable)
{
reflectionBindable.EnsureBindableChildren();
if (reflectionBindable.BindableChildren.Count == 0)
{
ourLog.Warn($"{reflectionBindable.GetType().ToString(true)} RdExt without bindable children was activated.");
}
reflectionBindable.OnActivated();
}
return instance;
}