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); } }
public Task Execute <TParameters>(IProxy proxy, MethodInfo methodInfo, ref TParameters parameters) where TParameters : IValueContainer { var serviceProxyContext = (ServiceProxyContext)proxy.Context; var methodDefinition = serviceProxyContext.Definition.FindMethod(methodInfo); if (methodDefinition == null || methodDefinition.IsIgnored) { var invoker = _methodInvokerFactory.Create(methodInfo); return(invoker.Invoke(proxy, parameters)); } var intent = new ExecuteRoutineIntent { Id = _idGenerator.NewId(), Service = serviceProxyContext.Descriptor.Id, Method = _routineMethodIdProvider.GetId(methodInfo), Parameters = parameters }; Type taskResultType = methodInfo.ReturnType == typeof(void) ? TaskAccessor.VoidTaskResultType : TaskAccessor.GetTaskResultType(methodInfo.ReturnType); var taskState = new RoutineReference { ServiceId = intent.Service, MethodId = intent.Method, IntentId = intent.Id #warning must have id of actual routine for dynamic subscription (subscribe after a routine already scheduled). }; var proxyTask = TaskAccessor.CreateTask(taskState, taskResultType); 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 methodSettings = _communicationSettingsProvider.GetMethodSettings(methodDefinition); if (methodSettings.IgnoreTransaction) { ignoreTransaction = true; } } if (ignoreTransaction) { ExecuteAndAwaitInBackground(intent, proxyTask); } else { _transitionScope.CurrentMonitor.RegisterIntent(intent, proxyTask); } return(proxyTask); }