/// <summary>
        /// Indicates whether a method should be considered an operation-contract (and if so: by what name)
        /// </summary>
        public virtual bool IsOperationContract(MethodInfo method, out string?name)
        {
            if (method.DeclaringType == typeof(object) || !method.IsPublic)
            {
                name = null;
                return(false);
            }

            string?opName  = null;
            var    attribs = AttributeHelper.For(method, inherit: true);

            if (attribs.IsDefined("ProtoBuf.Grpc.Configuration.OperationAttribute"))
            {
                attribs.TryGetAnyNonWhitespaceString("ProtoBuf.Grpc.Configuration.OperationAttribute", "Name", out opName);
            }
            else if (attribs.IsDefined("System.ServiceModel.OperationContractAttribute"))
            {
                attribs.TryGetAnyNonWhitespaceString("System.ServiceModel.OperationContractAttribute", "Name", out opName);
            }
            if (string.IsNullOrWhiteSpace(opName))
            {
                opName = GetDefaultName(method);
            }
            name = opName;
            return(!string.IsNullOrWhiteSpace(name));
        }
        /// <summary>
        /// Gets the default name for a potential data-contract
        /// </summary>
        protected virtual string GetDataContractName(Type contractType)
        {
            var attribs = AttributeHelper.For(contractType, inherit: false);

            if (attribs.TryGetAnyNonWhitespaceString("ProtoBuf.ProtoContractAttribute", "Name", out var name) ||
                attribs.TryGetAnyNonWhitespaceString("System.Runtime.Serialization.DataContractAttribute", "Name", out name))
            {
                return(name);
            }
            return(contractType.Name);
        }
        /// <summary>
        /// Indicates whether an interface should be considered a service-contract (and if so: by what name)
        /// </summary>
        public virtual bool IsServiceContract(Type contractType, out string?name)
        {
            if (typeof(IGrpcService).IsAssignableFrom(contractType))
            {
                name = contractType.Name;
                return(true);
            }

            string?serviceName;
            var    attribs = AttributeHelper.For(contractType, inherit: true);

            if (attribs.IsDefined("ProtoBuf.Grpc.Configuration.ServiceAttribute"))
            {
                attribs.TryGetAnyNonWhitespaceString("ProtoBuf.Grpc.Configuration.ServiceAttribute", "Name", out serviceName);
            }
            else if (attribs.IsDefined("System.ServiceModel.ServiceContractAttribute"))
            {
                attribs.TryGetAnyNonWhitespaceString("System.ServiceModel.ServiceContractAttribute", "Name", out serviceName);
            }
            else
            {
                name = default;
                return(false);
            }
            if (string.IsNullOrWhiteSpace(serviceName))
            {
                serviceName = GetDefaultName(contractType);
            }
            else if (contractType.IsGenericType)
            {
                var parts = GetGenericParts(contractType);
                serviceName = string.Format(serviceName, parts);
            }
            name = serviceName;
            return(!string.IsNullOrWhiteSpace(name));
        }
 public void CheckTypeAttributes(Type type, bool inherit, string expectedFoo, string expectedBar)
 => CheckResults(AttributeHelper.For(type, inherit), expectedFoo, expectedBar);