@@ -107,6 +107,105 @@ public void CreateInstance_PublicOnlyTypeWithPrivateDefaultConstructor_ThrowsMis
107
107
Assert . Throws < MissingMethodException > ( ( ) => Activator . CreateInstance ( typeof ( TypeWithPrivateDefaultConstructor ) , nonPublic : false ) ) ;
108
108
}
109
109
110
+ [ Fact ]
111
+ public void CreateInstance_WithCustomBinder_ThrowsMissingMethodException ( )
112
+ {
113
+ // MissingMethodException not caused by a binder must not contain an inner exception.
114
+ var mme = Assert . Throws < MissingMethodException > ( ( ) => Activator . CreateInstance ( typeof ( TypeWithPrivateDefaultConstructor ) , nonPublic : false ) ) ;
115
+ Assert . Contains ( "System.Tests.ActivatorTests+TypeWithPrivateDefaultConstructor" , mme . Message ) ;
116
+ Assert . Null ( mme . InnerException ) ;
117
+
118
+ mme = Assert . Throws < MissingMethodException > ( ( ) => Activator . CreateInstance ( typeof ( TypeWithoutDefaultCtor ) ) ) ;
119
+ Assert . Contains ( "System.Tests.ActivatorTests+TypeWithoutDefaultCtor" , mme . Message ) ;
120
+ Assert . Null ( mme . InnerException ) ;
121
+
122
+ // MissingMethodException caused by a binder must be wrapped.
123
+ mme = Assert . Throws < MissingMethodException > ( ( ) => Activator . CreateInstance (
124
+ typeof ( object ) , BindingFlags . CreateInstance ,
125
+ new CustomBinder ( ) { BindToMethodAction = ( ) => throw new MissingMethodException ( "Hello, World!!" ) } ,
126
+ null , null , null
127
+ ) ) ;
128
+ Assert . Contains ( "System.Object" , mme . Message ) ;
129
+ Assert . NotNull ( mme . InnerException ) ;
130
+ Assert . IsType < MissingMethodException > ( mme . InnerException ) ;
131
+ Assert . Equal ( "Hello, World!!" , mme . InnerException . Message ) ;
132
+
133
+ mme = Assert . Throws < MissingMethodException > ( ( ) => Activator . CreateInstance (
134
+ typeof ( Random ) , BindingFlags . CreateInstance ,
135
+ new CustomBinder ( ) { BindToMethodAction = ( ) => throw new MissingMethodException ( "good-bye..." ) } ,
136
+ null , null , null
137
+ ) ) ;
138
+ Assert . Contains ( "System.Random" , mme . Message ) ;
139
+ Assert . NotNull ( mme . InnerException ) ;
140
+ Assert . IsType < MissingMethodException > ( mme . InnerException ) ;
141
+ Assert . Equal ( "good-bye..." , mme . InnerException . Message ) ;
142
+
143
+ // Any other exceptions will not be caught.
144
+ Assert . Throws < Exception > ( ( ) => Activator . CreateInstance (
145
+ typeof ( object ) , BindingFlags . CreateInstance ,
146
+ new CustomBinder ( ) { BindToMethodAction = ( ) => throw new Exception ( ) } ,
147
+ null , null , null
148
+ ) ) ;
149
+ Assert . Throws < ArgumentNullException > ( ( ) => Activator . CreateInstance (
150
+ typeof ( object ) , BindingFlags . CreateInstance ,
151
+ new CustomBinder ( ) { BindToMethodAction = ( ) => throw new ArgumentNullException ( ) } ,
152
+ null , null , null
153
+ ) ) ;
154
+ Assert . Throws < FileNotFoundException > ( ( ) => Activator . CreateInstance (
155
+ typeof ( Random ) , BindingFlags . CreateInstance ,
156
+ new CustomBinder ( ) { BindToMethodAction = ( ) => throw new FileNotFoundException ( ) } ,
157
+ null , null , null
158
+ ) ) ;
159
+ Assert . Throws < InvalidOperationException > ( ( ) => Activator . CreateInstance (
160
+ typeof ( Random ) , BindingFlags . CreateInstance ,
161
+ new CustomBinder ( ) { BindToMethodAction = ( ) => throw new InvalidOperationException ( ) } ,
162
+ null , null , null
163
+ ) ) ;
164
+
165
+ // MissingMethodException must not contain an inner exception when BindToMethod returns null.
166
+ mme = Assert . Throws < MissingMethodException > ( ( ) => Activator . CreateInstance (
167
+ typeof ( object ) , BindingFlags . CreateInstance ,
168
+ new CustomBinder ( ) { BindToMethodAction = ( ) => null } ,
169
+ null , null , null
170
+ ) ) ;
171
+ Assert . Contains ( "System.Object" , mme . Message ) ;
172
+ Assert . Null ( mme . InnerException ) ;
173
+
174
+ mme = Assert . Throws < MissingMethodException > ( ( ) => Activator . CreateInstance (
175
+ typeof ( Random ) , BindingFlags . CreateInstance ,
176
+ new CustomBinder ( ) { BindToMethodAction = ( ) => null } ,
177
+ null , null , null
178
+ ) ) ;
179
+ Assert . Contains ( "System.Random" , mme . Message ) ;
180
+ Assert . Null ( mme . InnerException ) ;
181
+ }
182
+
183
+ class CustomBinder : Binder
184
+ {
185
+ public required Func < MethodBase ? > BindToMethodAction { get ; init ; }
186
+
187
+ public override MethodBase BindToMethod ( BindingFlags bindingAttr , MethodBase [ ] match , ref object ? [ ] args , ParameterModifier [ ] ? modifiers , CultureInfo ? culture , string [ ] ? names , out object ? state )
188
+ {
189
+ state = null ;
190
+ return this . BindToMethodAction ( ) ! ;
191
+ }
192
+
193
+ public override FieldInfo BindToField ( BindingFlags bindingAttr , FieldInfo [ ] match , object value , CultureInfo ? culture )
194
+ => throw new NotImplementedException ( ) ;
195
+
196
+ public override object ChangeType ( object value , Type type , CultureInfo ? culture )
197
+ => throw new NotImplementedException ( ) ;
198
+
199
+ public override void ReorderArgumentArray ( ref object ? [ ] args , object state )
200
+ => throw new NotImplementedException ( ) ;
201
+
202
+ public override MethodBase ? SelectMethod ( BindingFlags bindingAttr , MethodBase [ ] match , Type [ ] types , ParameterModifier [ ] ? modifiers )
203
+ => throw new NotImplementedException ( ) ;
204
+
205
+ public override PropertyInfo ? SelectProperty ( BindingFlags bindingAttr , PropertyInfo [ ] match , Type ? returnType , Type [ ] ? indexes , ParameterModifier [ ] ? modifiers )
206
+ => throw new NotImplementedException ( ) ;
207
+ }
208
+
110
209
[ Fact ]
111
210
public void CreateInstance_NullableType_ReturnsNull ( )
112
211
{
0 commit comments