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); }
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); }
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); } }
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); } }