示例#1
0
        /// <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);
        }
示例#2
0
        /// <summary>
        /// Сбрасывает аутентификацию соединения в изначальное состояние.
        /// </summary>
        public void SignOut()
        {
            if (Context == null)
            {
                ThrowHelper.ThrowVRpcException("Current server context is Null.");
            }

            Context.SignOut();
        }
示例#3
0
        /// <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.");
            }
        }
示例#4
0
 public static void Initialize(RecyclableMemoryStreamManager memoryManager)
 {
     if (Interlocked.CompareExchange(ref _memoryManager, memoryManager, null) == null)
     {
         return;
     }
     else
     {
         Debug.Assert(false, "MemoryManager уже инициализирован");
         ThrowHelper.ThrowVRpcException("MemoryManager уже инициализирован");
     }
 }
示例#5
0
        /// <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;
        }
示例#6
0
        /// <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;
        }
示例#7
0
        /// <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);
            }
        }
示例#8
0
        /// <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();
        }
示例#9
0
        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);
示例#10
0
        /// <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);
        }
示例#11
0
        /// <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));
        }
示例#12
0
 /// <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);
     }
 }
示例#13
0
        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}'." +
                                                       $" Переименуйте методы так что-бы их имена были уникальны в пределах контроллера.");
                    }
                }
            }
        }