public IEventPublisher GetPublisher(ServiceId serviceId, EventId eventId)
        {
            if (_eventingMethods.Count == 0)
            {
                throw new CommunicationMethodNotFoundException("There are no communication methods registered.");
            }

            IServiceDefinition serviceDefinition;
            IEventDefinition   eventDefinition;

            if (_serviceResolver.TryResolve(serviceId, out var serviceRef))
            {
                serviceDefinition = serviceRef.Definition;
                eventDefinition   = _eventResolver.Resolve(serviceDefinition, eventId).Definition;
            }
            else
            {
                throw new ServiceResolveException(serviceId);
            }

            lock (_publisherMap)
            {
                if (_publisherMap.TryGetValue(eventDefinition, out var cachedCommunicator))
                {
                    return(cachedCommunicator);
                }
            }

            var localSettings    = _communicationSettingsProvider.GetEventSettings(eventDefinition, external: false);
            var externalSettings = _communicationSettingsProvider.GetEventSettings(eventDefinition, external: true);

            var localEventingMethod    = GetEventingMethod(localSettings.CommunicationType);
            var externalEventingMethod = GetEventingMethod(externalSettings.CommunicationType);

            var localPublisher = localEventingMethod.CreateEventPublisher(GetConfiguration(eventDefinition));

            var publisher = localPublisher;

            if (externalEventingMethod.Type != localEventingMethod.Type)
            {
                var externalPublisher = externalEventingMethod.CreateEventPublisher(GetConfiguration(eventDefinition, forceExternal: true));
                publisher = new MulticastEventPublisher(localPublisher, externalPublisher);
            }

            lock (_publisherMap)
            {
                if (_publisherMap.TryGetValue(eventDefinition, out var cachedPublisher))
                {
                    (publisher as IDisposable)?.Dispose();
                    return(cachedPublisher);
                }

                _publisherMap.Add(eventDefinition, publisher);
                return(publisher);
            }
        }
Example #2
0
        public void RaiseEvent <TParameters>(IProxy proxy, EventInfo @event, ref TParameters parameters)
            where TParameters : IValueContainer
        {
            var serviceProxyContext = (ServiceProxyContext)proxy.Context;

            var intent = new RaiseEventIntent
            {
                Id         = _idGenerator.NewId(),
                Service    = serviceProxyContext.Descriptor.Id,
                Event      = _eventIdProvider.GetId(@event),
                Parameters = parameters
            };

            bool invokedByRunningMethod = _transitionScope.IsActive &&
                                          IsCalledByRoutine(
                _transitionScope.CurrentMonitor.Context,
                // Skip 2 stack frames: current method and dynamically-generated proxy.
                // WARNING! DO NOT PUT 'new StackFrame()' into a helper method!
                new StackFrame(skipFrames: 2, fNeedFileInfo: false));

            bool ignoreTransaction = !invokedByRunningMethod;

            if (!ignoreTransaction && _transitionScope.IsActive)
            {
                var runningMethodSettings = _communicationSettingsProvider.GetMethodSettings(
                    _transitionScope.CurrentMonitor.Context.MethodRef.Definition);

                if (!runningMethodSettings.Transactional)
                {
                    ignoreTransaction = true;
                }
            }

            if (!ignoreTransaction)
            {
                var eventDefinition = serviceProxyContext.Definition.FindEvent(@event);
                var eventSettings   = _communicationSettingsProvider.GetEventSettings(eventDefinition, external: false);
                if (eventSettings.IgnoreTransaction)
                {
                    ignoreTransaction = true;
                }
            }

            if (ignoreTransaction)
            {
                RaiseEventInBackground(intent);
            }
            else
            {
                _transitionScope.CurrentMonitor.RegisterIntent(intent);
            }
        }