/// <exception cref="VRpcException"/> public static Dictionary <string, Type> FindAllControllers(Assembly assembly) { var controllers = new Dictionary <string, Type>(StringComparer.InvariantCultureIgnoreCase); Type[] types = assembly.GetTypes();//.GetExportedTypes(); foreach (Type controllerType in types) { if (controllerType.IsSubclassOf(typeof(Controller))) { if (controllerType.IsPublic || IsInternal(controllerType)) { int ind = controllerType.Name.IndexOf("Controller", StringComparison.Ordinal); if (ind != -1) { // Имя без учета окончания 'Controller'. controllers.Add(controllerType.Name.Substring(0, ind), controllerType); } else { ThrowHelper.ThrowVRpcException($"Контроллер типа {controllerType.FullName} должен заканчиваться словом 'Controller'."); } } } } return(controllers); }
/// <summary> /// Сбрасывает аутентификацию соединения в изначальное состояние. /// </summary> public void SignOut() { if (Context == null) { ThrowHelper.ThrowVRpcException("Current server context is Null."); } Context.SignOut(); }
/// <exception cref="VRpcException"/> private void ValidateNotification(string methodName) { Debug.Assert(IsNotificationRequest); if (ReturnType != typeof(VoidStruct) && ReturnType != typeof(Task) && ReturnType != typeof(ValueTask)) { ThrowHelper.ThrowVRpcException($"Метод '{methodName}' помечен атрибутом [Notification] поэтому " + $"возвращаемый тип метода может быть только void или Task или ValueTask."); } }
public static void Initialize(RecyclableMemoryStreamManager memoryManager) { if (Interlocked.CompareExchange(ref _memoryManager, memoryManager, null) == null) { return; } else { Debug.Assert(false, "MemoryManager уже инициализирован"); ThrowHelper.ThrowVRpcException("MemoryManager уже инициализирован"); } }
/// <exception cref="VRpcException"/> /// <exception cref="ObjectDisposedException"/> public void ConfigureAutoAuthentication(Func <AccessToken> configure) { if (configure == null) { ThrowHelper.ThrowArgumentNullException(nameof(configure)); } ThrowIfDisposed(); if (_autoAuthentication != null) { ThrowHelper.ThrowVRpcException("Auto authentication already configured."); } _autoAuthentication = configure; }
/// <exception cref="VRpcException"/> /// <exception cref="ObjectDisposedException"/> public void Configure(Action <ApplicationBuilder> configureApp) { if (configureApp == null) { ThrowHelper.ThrowArgumentNullException(nameof(configureApp)); } ThrowIfDisposed(); if (_configureApp != null) { ThrowHelper.ThrowVRpcException("RpcClient already configured."); } _configureApp = configureApp; }
/// <summary> /// Сериализует объект в JSON. /// </summary> /// <exception cref="VRpcException"/> public static void SerializeObjectJson(ArrayBufferWriter <byte> destination, object instance) { // Сериализовать Null не нужно (Отправлять тело сообщения при этом тоже не нужно). Debug.Assert(instance != null, "Сериализовать и отправлять Null не нужно"); try { using (var writer = new Utf8JsonWriter(destination)) { JsonSerializer.Serialize(writer, instance /*, new JsonSerializerOptions { IgnoreNullValues = true }*/); } } catch (Exception ex) { ThrowHelper.ThrowVRpcException($"Не удалось сериализовать объект типа {instance.GetType().FullName} в json.", ex); } }
/// <summary> /// Позволяет настроить IoC контейнер. /// Выполняется единожды при инициализации подключения. /// </summary> /// <exception cref="VRpcException"/> /// <exception cref="ArgumentNullException"/> /// <exception cref="ObjectDisposedException"/> public void ConfigureService(Action <ServiceCollection> configure) { if (configure == null) { ThrowHelper.ThrowArgumentNullException(nameof(configure)); } ThrowIfDisposed(); if (ServiceProvider != null) { ThrowHelper.ThrowVRpcException("Service already configured."); } configure(_serviceCollection); ServiceProvider = _serviceCollection.BuildServiceProvider(); }
private static string ControllerNameFromTypeName(Type interfaceType) { #if NETSTANDARD2_0 || NET472 bool startsWithI = interfaceType.Name.StartsWith("I", StringComparison.Ordinal); #else bool startsWithI = interfaceType.Name.StartsWith('I'); #endif // Нужно игнорировать окончание 'Controller' int controllerWordIndex = interfaceType.Name.LastIndexOf("Controller", StringComparison.OrdinalIgnoreCase); string controllerName; if (controllerWordIndex != -1) // Оканчивается на 'Controller'. { if (startsWithI) { controllerName = interfaceType.Name.Substring(1, controllerWordIndex - 1); } else { controllerName = interfaceType.Name.Substring(0, controllerWordIndex); } } else // Не оканчивается на 'Controller'. { if (startsWithI) { controllerName = interfaceType.Name.Substring(1); } else { controllerName = interfaceType.Name; } } if (controllerName.Length > 0) { return(controllerName); } else { ThrowHelper.ThrowVRpcException($"Пометьте интерфейс {interfaceType.FullName} атрибутом [ControllerContract] или задайте другое имя."); return(default);
/// <summary> /// Сериализует заголовок. /// </summary> /// <param name="stream"></param> /// <param name="headerSize"></param> public void SerializeProtoBuf(Stream stream, out int headerSize) { int initialPos = (int)stream.Position; // Сериализуем хедэр. ProtoBufSerializer.Serialize(stream, this); headerSize = (int)stream.Position - initialPos; Debug.Assert(headerSize <= HeaderMaxSize); if (headerSize <= HeaderMaxSize) { return; } ThrowHelper.ThrowVRpcException(HeaderSizeExceededException); }
/// <exception cref="VRpcException"/> public BearerToken CreateAccessToken(ClaimsPrincipal claimsPrincipal, TimeSpan validTime) { if (claimsPrincipal == null) { ThrowHelper.ThrowArgumentNullException(nameof(claimsPrincipal)); } if (validTime < TimeSpan.Zero) { ThrowHelper.ThrowArgumentOutOfRangeException(nameof(validTime)); } if (Context == null) { ThrowHelper.ThrowVRpcException("Current server context is Null."); } return(Context.CreateAccessToken(claimsPrincipal, validTime)); }
/// <exception cref="VRpcException"/> private static bool IsAllParametersIsSpecialType(MethodInfo interfaceMethod) { ParameterInfo[]? prms = interfaceMethod.GetParameters(); Debug.Assert(prms != null); if (prms.Length > 0) { bool allIsContentType = prms.All(x => typeof(VRpcContent).IsAssignableFrom(x.ParameterType)); if (!allIsContentType) { if (prms.Any(x => typeof(VRpcContent).IsAssignableFrom(x.ParameterType))) { ThrowHelper.ThrowVRpcException($"Все параметры должны быть либо производными типа {nameof(VRpcContent)} либо любыми другими типами"); } } return(allIsContentType); } else { return(false); } }
public InvokeActionsDictionary(Dictionary <string, Type> controllers) { // Методы типа "home/hello" без учета регистра. _actionsDict = new Dictionary <string, ControllerMethodMeta>(StringComparer.OrdinalIgnoreCase) { { "/SignIn", new ControllerMethodMeta("SignIn", typeof(AccountController), AccountController.SignInMethod) }, { "/SignOut", new ControllerMethodMeta("SignOut", typeof(AccountController), AccountController.SignOutMethod) } }; foreach (KeyValuePair <string, Type> controller in controllers) { MethodInfo[] methods = controller.Value.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance); foreach (MethodInfo method in methods) { string actionFullName = $"{controller.Key}{GlobalVars.ControllerNameSplitter}{method.Name}"; if (!_actionsDict.TryAdd(actionFullName, new ControllerMethodMeta(actionFullName, controller.Value, method))) { ThrowHelper.ThrowVRpcException($"Контроллер {controller.Value.Name} содержит несколько методов с одинаковым именем '{method.Name}'." + $" Переименуйте методы так что-бы их имена были уникальны в пределах контроллера."); } } } }