Beispiel #1
0
 public SessionContract(TalkCompositionHost source, ISession session, object[] localServiceInstances, object[] remoteServiceInstances)
 {
     this.Session        = session;
     this.RemoteServices = remoteServiceInstances;
     this.LocalServices  = localServiceInstances;
     this.source         = source;
 }
Beispiel #2
0
        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.");
                    }
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
            }
        }