示例#1
0
        private ServiceAndMethodDefinitions Resolve(ServiceId serviceId, MethodId methodId, bool assumeExternal = false)
        {
            var result = new ServiceAndMethodDefinitions();

            if (_serviceResolver.TryResolve(serviceId, out var serviceRef))
            {
                result.Service = serviceRef.Definition;

                // NOTE: system services are not unique within a multi-service ecosystem, thus must
                // use the configuration of the calling (proxy) service without any specific method.
                // Otherwise, a continuation can be sent to a wrong instance of a system service.
                if (result.Service.Type == ServiceType.System && !string.IsNullOrEmpty(serviceId.Proxy))
                {
                    return(Resolve(new ServiceId {
                        Name = serviceId.Proxy
                    }, null, assumeExternal));
                }

                result.Method = methodId == null ? null : _methodResolver.Resolve(result.Service, methodId).Definition;
            }
            else if (assumeExternal)
            {
                var externalServiceDefinition = _externalCommunicationModel.GetOrAddService(serviceId);
                var externalMethodDefinition  = methodId == null ? null : externalServiceDefinition.GetOrAddMethod(methodId);
                result.Service = externalServiceDefinition;
                result.Method  = externalMethodDefinition;
            }
            else
            {
                throw new ServiceResolveException(serviceId);
            }

            return(result);
        }
示例#2
0
        private async Task <InvokeRoutineResult> RunRoutineAsync(
            ITransitionCarrier transitionCarrier,
            TransitionDescriptor transitionDescriptor,
            CancellationToken ct)
        {
            var invocationResult = new InvokeRoutineResult();

            using (_transitionScope.Enter(transitionDescriptor))
            {
                var transitionMonitor = _transitionScope.CurrentMonitor;

                var serviceId = await transitionCarrier.GetServiceIdAsync(ct);

                var methodId = await transitionCarrier.GetRoutineDescriptorAsync(ct);

                var serviceReference = _serviceResolver.Resolve(serviceId);
                var methodReference  = _methodResolver.Resolve(serviceReference.Definition, methodId);

                object serviceInstance = serviceReference.GetInstance();

                //var serviceStateContainer = _serviceStateValueContainerProvider.CreateContainer(serviceInstance);
                //var isStatefullService = serviceStateContainer.GetCount() > 0;
                //if (isStatefullService)
                //    await transitionCarrier.ReadServiceStateAsync(serviceStateContainer, ct);

                Type taskResultType =
                    methodReference.Definition.MethodInfo.ReturnType == typeof(void)
                    ? TaskAccessor.VoidTaskResultType
                    : TaskAccessor.GetTaskResultType(methodReference.Definition.MethodInfo.ReturnType);

                Task            completionTask;
                IValueContainer asmValueContainer = null;

                if (TryCreateAsyncStateMachine(methodReference.Definition.MethodInfo, methodId.IntentId, out var asmInstance, out var asmMetadata))
                {
                    var isContinuation = transitionDescriptor.Type == TransitionType.ContinueRoutine;
                    asmValueContainer = await LoadRoutineStateAsync(transitionCarrier, asmInstance, asmMetadata, isContinuation, ct);

                    asmMetadata.Owner.FieldInfo?.SetValue(asmInstance, serviceInstance);

                    transitionMonitor.OnRoutineStart(
                        serviceReference,
                        methodReference,
                        methodId,
                        serviceInstance,
                        asmInstance,
                        (transitionCarrier as TransitionCarrier)?.Caller);

                    try
                    {
                        asmInstance.MoveNext();
                        completionTask = GetCompletionTask(asmInstance, asmMetadata);
                    }
                    catch (Exception ex)
                    {
                        // The MoveNext() must not throw, but instead complete the task with an error.
                        // try-catch is added just in case for a non-compiler-generated state machine.
                        completionTask = TaskAccessor.FromException(taskResultType, ex);
                    }
                }
        public Unit VisitInlineMethod(Instruction instruction, MethodReference operand)
        {
            MarkLabel(instruction);

            MethodBase method = _methodResolver.Resolve(operand);

            MethodInfo methodInfo = method as MethodInfo;

            if (methodInfo != null)
            {
                _generator.Emit(_opCodeMapper.Map(instruction.OpCode), methodInfo);
            }
            else
            {
                ConstructorInfo constructor = (ConstructorInfo)method;
                _generator.Emit(_opCodeMapper.Map(instruction.OpCode), constructor);
            }

            return(Unit.Value);
        }
示例#4
0
        public void ResolveRequestWithoutSession(IMethodResolver methodResolver, IAttachmentResolver attachmentResolver)
        {
            methodResolver.MethodText         = MethodText;
            attachmentResolver.AttachmentText = AttachmentText;

            RequestMethod     = methodResolver.Resolve();
            RequestAttachment = attachmentResolver.Resolve();

            if (methodResolver.Error.Level == ErrorLevels.NeedNotice)
            {
                Error.Errors.Add(methodResolver.Error);
            }
            if (attachmentResolver.Error.Level == ErrorLevels.NeedNotice)
            {
                Error.Errors.Add(attachmentResolver.Error);
            }
        }
        private IEnumerable <Tuple <MethodBase, object> > FindEventAddRemoveAccessors(Action action)
        {
            DisassembleResult disassembleResult = _methodDisassembler.Disassemble(action.Method);

            foreach (Instruction instruction in disassembleResult.Body.Instructions)
            {
                MethodReference calledMethod;
                if (_instructionHelper.TryGetCall(instruction, out calledMethod))
                {
                    if (IsEventAddRemoveMethod(calledMethod))
                    {
                        object target = calledMethod.HasThis
                            ? GetInvocationTarget(disassembleResult.Body, instruction, action.Target)
                            : null;

                        MethodBase method = _methodResolver.Resolve(calledMethod);

                        yield return(Tuple.Create(method, target));
                    }
                }
            }
        }
        public void ResolveRequest(IMethodResolver methodResolver, ISessionResolver sessionResolver,
                                   IAttachmentResolver attachmentResolver)
        {
            methodResolver.MethodText = MethodText;
            sessionResolver.SessionText = SessionText;
            attachmentResolver.AttachmentText = AttachmentText;

            RequestMethod = methodResolver.Resolve();
            Session = sessionResolver.Resolve();
            RequestAttachment = attachmentResolver.Resolve();

            if (methodResolver.Error.Level == ErrorLevels.NeedNotice)
            {
                Error.Errors.Add(methodResolver.Error);
            }
            if (attachmentResolver.Error.Level == ErrorLevels.NeedNotice)
            {
                Error.Errors.Add(attachmentResolver.Error);
            }
            if (sessionResolver.Error.Level == ErrorLevels.NeedNotice)
            {
                Error.Errors.Add(sessionResolver.Error);
            }
        }
示例#7
0
        public IMethodStateStorage GetStorage(ServiceId serviceId, MethodId methodId, bool returnNullIfNotFound = false)
        {
            if (_persistenceMethods.Count == 0)
            {
                if (returnNullIfNotFound)
                {
                    return(null);
                }
                else
                {
                    throw new MethodStateStorageNotFoundException("There are no method state storages registered.");
                }
            }

            var serviceRef = _serviceResolver.Resolve(serviceId);
            var methodRef  = _methodResolver.Resolve(serviceRef.Definition, methodId);

            lock (_storageMap)
            {
                if (_storageMap.TryGetValue(methodRef.Definition, out var cachedStorage))
                {
                    return(cachedStorage);
                }
            }

            var serviceCategory = serviceRef.Definition.Type == ServiceType.External ? "_external" : "_local";
            var methodCategory  = methodRef.Definition.IsQuery ? "queries" : "commands";

            var persistenceType = _communicationSettingsProvider.GetMethodSettings(methodRef.Definition).PersistenceType;

            IPersistenceMethod persistenceMethod;

            if (string.IsNullOrWhiteSpace(persistenceType))
            {
                if (_persistenceMethods.Count == 1)
                {
                    persistenceMethod = _persistenceMethods.First().Value;
                }
                else
                {
                    if (returnNullIfNotFound)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new MethodStateStorageNotFoundException("Multiple method state storages are available.");
                    }
                }
            }
            else
            {
                if (!_persistenceMethods.TryGetValue(persistenceType, out persistenceMethod))
                {
                    if (returnNullIfNotFound)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new MethodStateStorageNotFoundException($"Method state storage '{persistenceType}' is not registered.");
                    }
                }
            }

            var servicesSection = _configuration.GetSection("services");
            var serviceSection  = servicesSection.GetSection(serviceRef.Definition.Name);

            var storageConfig = GetConfiguraion(
                _configuration.GetSection("persistence"),
                _configuration.GetSection(methodCategory).GetSection("persistence"),
                servicesSection.GetSection(serviceCategory).GetSection("persistence"),
                servicesSection.GetSection(serviceCategory).GetSection(methodCategory).GetSection("persistence"),
                serviceSection.GetSection("persistence"),
                serviceSection.GetSection(methodCategory).GetSection("_all").GetSection("persistence"),
                serviceSection.GetSection(methodCategory).GetSection(methodRef.Definition.Name).GetSection("persistence"));

            var storage = persistenceMethod.CreateMethodStateStorage(storageConfig);

            lock (_storageMap)
            {
                if (_storageMap.TryGetValue(methodRef.Definition, out var cachedStorage))
                {
                    (storage as IDisposable)?.Dispose();
                    return(cachedStorage);
                }

                _storageMap.Add(methodRef.Definition, storage);
                return(storage);
            }
        }