public SessionContract(TalkCompositionHost source, ISession session, object[] localServiceInstances, object[] remoteServiceInstances) { this.Session = session; this.RemoteServices = remoteServiceInstances; this.LocalServices = localServiceInstances; this.source = source; }
internal void CheckOutParamsSubscriptions(object instance, object[] outParams, TalkCompositionHost host, Type targetInterface) { if (outParams != null) { // todo: subscribe action foreach (var outParam in outParams) { if (outParam is Delegate) { Delegate sessionDelegate = (Delegate)outParam; var method = sessionDelegate.Method; string methodName = method.Name; var parameters = method.GetParameters(); Type serviceDelegateType = null; foreach (var p in parameters) { if (p.ParameterType != typeof(int) && p.ParameterType != typeof(string)) { serviceDelegateType = p.ParameterType; break; } } if (methodName.EndsWith("Created", false, CultureInfo.InvariantCulture)) { SessionChangeSubscription subscription; if (!sessionCreatedSubscriptions.TryGetValue(serviceDelegateType, out subscription)) { subscription = new SessionChangeSubscription(serviceDelegateType); sessionCreatedSubscriptions.Add(serviceDelegateType, subscription); if (!CheckIfSubscriptionInterfaceIsRegistered(serviceDelegateType)) { throw new InvalidOperationException($"Cannot subscribe session events for {serviceDelegateType.FullName}! No registration was found in the assigned container hosts. Are you missing a RegisterRemoteService<{serviceDelegateType.Name}>()?"); } } if (host != null && host.IsSessionInstance(targetInterface, out ISession session)) { subscription.AddDelegate(sessionDelegate, parameters, session); } else { subscription.AddDelegate(sessionDelegate, parameters, null); } } else if (methodName.EndsWith("Terminated", false, CultureInfo.InvariantCulture)) { SessionChangeSubscription subscription; if (!sessionTerminatedSubscriptions.TryGetValue(serviceDelegateType, out subscription)) { subscription = new SessionChangeSubscription(serviceDelegateType); sessionTerminatedSubscriptions.Add(serviceDelegateType, subscription); if (!CheckIfSubscriptionInterfaceIsRegistered(serviceDelegateType)) { throw new InvalidOperationException($"Cannot subscribe session events for {serviceDelegateType.FullName}! No registration was found in the assigned container hosts. Are you missing a RegisterRemoteService<{serviceDelegateType.Name}>()?"); } } if (host != null && host.IsSessionInstance(targetInterface, out ISession session)) { subscription.AddDelegate(sessionDelegate, parameters, session); } else { subscription.AddDelegate(sessionDelegate, parameters, null); } } else { throw new NotSupportedException($"The Action subscription method name \"{methodName}\" is not supported! Method name must end either with \"Created\" or \"Terminated\"."); } } else { throw new InvalidOperationException($"Unexpected out parameter in \"{instance.GetType().FullName}\" constructor! Only delegate types (e.g. Action<IMyService>) are allowed."); } } } }
internal IEnumerable CollectLocalMultiImports(TalkCompositionHost host, Type type, Type injectTargetType, List <Type> pendingCreateList) { // multiple imports // 1. determine generic target interface type // 2. create concreate target collection instance // 3. add one instance of all local implementations Type genericCollectionInterface = type.GetInterface("IEnumerable`1"); if (type.IsGenericType || genericCollectionInterface != null) { Type enumerableClassType = null; Type[] genericTypes = type.GetGenericArguments(); if (genericTypes.Length == 1) { Type listType = typeof(List <>); enumerableClassType = listType.MakeGenericType(genericTypes); } else if (genericTypes.Length == 0 && genericCollectionInterface != null) { genericTypes = genericCollectionInterface.GetGenericArguments(); Type listType = typeof(List <>); enumerableClassType = listType.MakeGenericType(genericTypes); } if (enumerableClassType != null && genericTypes.Length == 1) { Type targetInterfaceType = genericTypes[0]; bool isShared = IsMultiShared(targetInterfaceType); IList targetCollection = null; if (isShared) { targetCollection = GetLocalSharedMultipleInstances(targetInterfaceType); } if (targetCollection == null) { targetCollection = (IList)TypeService.CreateInstance(enumerableClassType); // create new instances HashSet <Type> createdTypes = new HashSet <Type>(); foreach (Type implType in this.FindInterfaceImplementations(targetInterfaceType, injectTargetType)) { if (!createdTypes.Contains(implType) && injectTargetType != implType) { object[] outParams; ParameterInfo[] outParamsInfo; object itemInstance; if (host != null) { itemInstance = TypeService.CreateInstance(implType, host.DetermineConstructorImportInstance, pendingCreateList, out outParams, out outParamsInfo); } else { itemInstance = TypeService.CreateInstance(implType, this.DetermineConstructorImportInstance, pendingCreateList, out outParams, out outParamsInfo); } CheckOutParamsSubscriptions(itemInstance, outParams, host, targetInterfaceType); targetCollection.Add(itemInstance); RegisterSharedConstructorInstances(targetInterfaceType, itemInstance, outParams, outParamsInfo); createdTypes.Add(implType); } } if (isShared) { if (localSharedMultipleInterfaceInstances == null) { localSharedMultipleInterfaceInstances = new Dictionary <Type, IList>(); } // add to shared dictionary localSharedMultipleInterfaceInstances.Add(targetInterfaceType, targetCollection); } } if (type.IsArray) { Type arrayItemType = type.GetElementType(); Array targetArray = Array.CreateInstance(arrayItemType, targetCollection.Count); for (int i = 0; i < targetCollection.Count; i++) { targetArray.SetValue(targetCollection[i], i); } return(targetArray); } else { return(targetCollection); } } } return(null); }
internal bool TryRaiseInMemorySessionCreated(Type serviceType, object serviceInstance, TalkCompositionHost host, IGenericCommunicationService communicationService) { SessionChangeSubscription subscr; if (sessionCreatedSubscriptions.TryGetValue(serviceType, out subscr)) { if (inMemorySession == null) { inMemorySession = new Session(communicationService, 0, "In-Memory Session"); inMemorySessionContract = new SessionContract(host, inMemorySession, new object[0], new object[0]); } subscr.Invoke(serviceInstance, inMemorySessionContract, inMemorySession); return(true); } else { return(false); } }