diff --git a/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs
index 2ee0abe1d0a..59802e30787 100644
--- a/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs
+++ b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs
@@ -15,6 +15,7 @@
#endregion
using System;
+using System.Diagnostics.CodeAnalysis;
namespace Grpc.Core
{
@@ -29,12 +30,16 @@ namespace Grpc.Core
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class BindServiceMethodAttribute : Attribute
{
+ // grpc-dotnet uses reflection to find the bind service method.
+ // DynamicallyAccessedMembersAttribute instructs the linker to never trim the method.
+ private const DynamicallyAccessedMemberTypes ServiceBinderAccessibility = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
+
///
/// Initializes a new instance of the class.
///
/// The type the service bind method is defined on.
/// The name of the service bind method.
- public BindServiceMethodAttribute(Type bindType, string bindMethodName)
+ public BindServiceMethodAttribute([DynamicallyAccessedMembers(ServiceBinderAccessibility)] Type bindType, string bindMethodName)
{
BindType = bindType;
BindMethodName = bindMethodName;
@@ -43,6 +48,7 @@ namespace Grpc.Core
///
/// Gets the type the service bind method is defined on.
///
+ [DynamicallyAccessedMembers(ServiceBinderAccessibility)]
public Type BindType { get; }
///
diff --git a/src/csharp/Grpc.Core.Api/Internal/CodeAnalysisAttributes.cs b/src/csharp/Grpc.Core.Api/Internal/CodeAnalysisAttributes.cs
new file mode 100644
index 00000000000..e235cae418e
--- /dev/null
+++ b/src/csharp/Grpc.Core.Api/Internal/CodeAnalysisAttributes.cs
@@ -0,0 +1,146 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ ///
+ /// Indicates that certain members on a specified are accessed dynamically,
+ /// for example through .
+ ///
+ ///
+ /// This allows tools to understand which members are being accessed during the execution
+ /// of a program.
+ ///
+ /// This attribute is valid on members whose type is or .
+ ///
+ /// When this attribute is applied to a location of type , the assumption is
+ /// that the string represents a fully qualified type name.
+ ///
+ /// If the attribute is applied to a method it's treated as a special case and it implies
+ /// the attribute should be applied to the "this" parameter of the method. As such the attribute
+ /// should only be used on instance methods of types assignable to System.Type (or string, but no methods
+ /// will use it there).
+ ///
+ [AttributeUsage(
+ AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
+ AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method,
+ Inherited = false)]
+ internal sealed class DynamicallyAccessedMembersAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified member types.
+ ///
+ /// The types of members dynamically accessed.
+ public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
+ {
+ MemberTypes = memberTypes;
+ }
+
+ ///
+ /// Gets the which specifies the type
+ /// of members dynamically accessed.
+ ///
+ public DynamicallyAccessedMemberTypes MemberTypes { get; }
+ }
+
+ ///
+ /// Specifies the types of members that are dynamically accessed.
+ ///
+ /// This enumeration has a attribute that allows a
+ /// bitwise combination of its member values.
+ ///
+ [Flags]
+ internal enum DynamicallyAccessedMemberTypes
+ {
+ ///
+ /// Specifies no members.
+ ///
+ None = 0,
+
+ ///
+ /// Specifies the default, parameterless public constructor.
+ ///
+ PublicParameterlessConstructor = 0x0001,
+
+ ///
+ /// Specifies all public constructors.
+ ///
+ PublicConstructors = 0x0002 | PublicParameterlessConstructor,
+
+ ///
+ /// Specifies all non-public constructors.
+ ///
+ NonPublicConstructors = 0x0004,
+
+ ///
+ /// Specifies all public methods.
+ ///
+ PublicMethods = 0x0008,
+
+ ///
+ /// Specifies all non-public methods.
+ ///
+ NonPublicMethods = 0x0010,
+
+ ///
+ /// Specifies all public fields.
+ ///
+ PublicFields = 0x0020,
+
+ ///
+ /// Specifies all non-public fields.
+ ///
+ NonPublicFields = 0x0040,
+
+ ///
+ /// Specifies all public nested types.
+ ///
+ PublicNestedTypes = 0x0080,
+
+ ///
+ /// Specifies all non-public nested types.
+ ///
+ NonPublicNestedTypes = 0x0100,
+
+ ///
+ /// Specifies all public properties.
+ ///
+ PublicProperties = 0x0200,
+
+ ///
+ /// Specifies all non-public properties.
+ ///
+ NonPublicProperties = 0x0400,
+
+ ///
+ /// Specifies all public events.
+ ///
+ PublicEvents = 0x0800,
+
+ ///
+ /// Specifies all non-public events.
+ ///
+ NonPublicEvents = 0x1000,
+
+ ///
+ /// Specifies all members.
+ ///
+ All = ~None
+ }
+}