Skip to content

Commit be7d8ac

Browse files
committed
Use safe GetConstructor extension everywhere
1 parent d44b997 commit be7d8ac

9 files changed

Lines changed: 25 additions & 29 deletions

File tree

shared/Extensions/ReflectionExtensions.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ public static MethodInfo SafeGetMethod(this Type type, string methodName, Bindin
4040
return method;
4141
}
4242

43-
public static ConstructorInfo GetConstructor(this Type implementationType, params Type[] constructorSignature)
43+
public static ConstructorInfo GetConstructorSafe(this Type implementationType, params Type[] constructorSignature) => GetConstructorSafe(implementationType, BindingFlags.Instance | BindingFlags.Public, constructorSignature);
44+
public static ConstructorInfo GetConstructorSafe(this Type implementationType, BindingFlags bindingFlags, params Type[] constructorSignature)
4445
{
45-
foreach (ConstructorInfo constructor in implementationType.GetConstructors())
46+
foreach (ConstructorInfo constructor in implementationType.GetConstructors(bindingFlags))
4647
{
4748
if (constructorSignature.SequenceEqual(constructor.GetParameters().Select(x => x.ParameterType)))
4849
return constructor;
4950
}
5051

51-
throw new InvalidOperationException($"Could not find constructor ({String.Join(", ", constructorSignature.Select(x => x.ToString()))}) on type: {implementationType}");
52+
throw new InvalidOperationException($"Could not find constructor {implementationType.Name}({String.Join(", ", constructorSignature.Select(x => x.ToString()))}) [{bindingFlags}]");
5253
}
5354
}
5455
}

src/Dibix.Sdk.Cli/TaskRunner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private static IEnumerable<TaskRegistration> CollectTasks()
5555
throw new InvalidOperationException($"Type '{type}' is decorated with {nameof(TaskAttribute)}, but does not implement '{taskInterfaceType}'.");
5656

5757
bool supportsInputConfiguration = type.GetCustomAttributes<TaskPropertyAttribute>().Any(x => x.Source == TaskPropertySource.Core);
58-
ConstructorInfo ctor = type.GetConstructor(ConstructorSignature);
58+
ConstructorInfo ctor = type.GetConstructorSafe(ConstructorSignature);
5959

6060
ParameterExpression loggerParameter = Expression.Parameter(typeof(ILogger), "logger");
6161
ParameterExpression inputConfigurationParameter = Expression.Parameter(typeof(InputConfiguration), "inputConfiguration");

src/Dibix.Sdk.CodeAnalysis/SqlCodeAnalysisRuleMap.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private static IEnumerable<RuleRegistration> ScanRules()
4343
private static Func<SqlCodeAnalysisContext, IEnumerable<SqlCodeAnalysisError>> CompileRuleInvoker(Type ruleType)
4444
{
4545
ParameterExpression contextParameter = Expression.Parameter(typeof(SqlCodeAnalysisContext), "context");
46-
ConstructorInfo ctor = ruleType.GetConstructor(typeof(SqlCodeAnalysisContext));
46+
ConstructorInfo ctor = ruleType.GetConstructorSafe(typeof(SqlCodeAnalysisContext));
4747
Expression ruleInstance = Expression.New(ctor, contextParameter);
4848
MethodInfo analyzeMethod = typeof(ISqlCodeAnalysisRule).SafeGetMethod(nameof(ISqlCodeAnalysisRule.Analyze));
4949
Expression fragment = Expression.Property(contextParameter, nameof(SqlCodeAnalysisContext.Fragment));

src/Dibix.Sdk.Sql/PublicSqlDataSchemaModelLoader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ private static LoadPublicDataSchemaModel CompileModelFactory()
122122
// TaskLoggingHelper loggingHelper = new TaskLoggingHelper(task);
123123
Type loggingHelperType = typeof(TaskLoggingHelper);
124124
ParameterExpression loggingHelperVariable = Expression.Variable(loggingHelperType, "loggingHelper");
125-
ConstructorInfo loggingHelperCtor = loggingHelperType.GetConstructor(new[] { typeof(ITask) });
125+
ConstructorInfo loggingHelperCtor = loggingHelperType.GetConstructorSafe(typeof(ITask));
126126
Expression loggingHelperValue = Expression.New(loggingHelperCtor, taskParameter);
127127
Expression loggingHelperAssign = Expression.Assign(loggingHelperVariable, loggingHelperValue);
128128

@@ -173,7 +173,7 @@ private static LoadPublicDataSchemaModel CompileModelFactory()
173173
Expression loadedTaskHostProperty = Expression.Property(hostLoaderVariable, "LoadedTaskHost");
174174
MemberExpression modelProperty = Expression.Property(loadedTaskHostProperty, "Model");
175175
Type dataSchemaModelType = DacReflectionUtility.SchemaSqlAssembly.GetType("Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModel", true);
176-
ConstructorInfo modelCtor = typeof(TSqlModel).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { dataSchemaModelType }, null);
176+
ConstructorInfo modelCtor = typeof(TSqlModel).GetConstructorSafe(BindingFlags.NonPublic | BindingFlags.Instance, dataSchemaModelType);
177177
Expression modelValue = Expression.New(modelCtor, modelProperty);
178178

179179

src/Dibix.Sdk.Sql/SchemaAnalyzer.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private static AnalyzeSchema CompileAnalyzer()
7575
Expression lazyExport = Expression.Field(null, typeof(SchemaAnalyzer), nameof(LazyExport));
7676
Type extensionDescriptorType = SchemaSqlAssembly.GetType("Microsoft.SqlServer.Dac.Extensibility.ExtensionDescriptor`2", true)
7777
.MakeGenericType(typeof(SqlAnalysisRule), typeof(ISqlAnalysisRuleMetadata));
78-
ConstructorInfo extensionDescriptorCtor = extensionDescriptorType.GetConstructor(new[] { lazyExport.Type });
78+
ConstructorInfo extensionDescriptorCtor = extensionDescriptorType.GetConstructorSafe(lazyExport.Type);
7979
Guard.IsNotNull(extensionDescriptorCtor, nameof(extensionDescriptorCtor), "Could not find constructor on ExtensionDescriptor<,>");
8080
ParameterExpression extensionDescriptorVariable = Expression.Variable(extensionDescriptorType, "extensionDescriptor");
8181
Expression extensionDescriptorValue = Expression.New(extensionDescriptorCtor, lazyExport);
@@ -84,15 +84,15 @@ private static AnalyzeSchema CompileAnalyzer()
8484
// RuleDescriptor ruleDescriptor = new RuleDescriptorImpl(extensionDescriptor);
8585
Type ruleDescriptorType = DacExtensionsAssembly.GetType("Microsoft.SqlServer.Dac.CodeAnalysis.RuleDescriptor", true);
8686
Type ruleDescriptorImplType = DacExtensionsAssembly.GetType("Microsoft.SqlServer.Dac.CodeAnalysis.Engine.RuleDescriptorImpl", true);
87-
ConstructorInfo ruleDescriptorImplCtor = ruleDescriptorImplType.GetConstructor(new[] { extensionDescriptorType });
87+
ConstructorInfo ruleDescriptorImplCtor = ruleDescriptorImplType.GetConstructorSafe(extensionDescriptorType);
8888
Guard.IsNotNull(ruleDescriptorImplCtor, nameof(ruleDescriptorImplCtor), "Could not find constructor on RuleDescriptorImpl");
8989
ParameterExpression ruleDescriptorVariable = Expression.Variable(ruleDescriptorType, "ruleDescriptor");
9090
Expression ruleDescriptorValue = Expression.New(ruleDescriptorImplCtor, extensionDescriptorVariable);
9191
Expression ruleDescriptorAssign = Expression.Assign(ruleDescriptorVariable, ruleDescriptorValue);
9292

9393
// NullableColumnSchemaAnalyzer nullableColumnSchemaAnalyzer = new NullableColumnSchemaAnalyzer(ruleDescriptor, dataSchemaModel, modelElement);
9494
Type nullableColumnSchemaAnalyzerType = DacExtensionsAssembly.GetType("Microsoft.SqlServer.Dac.CodeAnalysis.Rules.Performance.NullableColumnSchemaAnalyzer");
95-
ConstructorInfo nullableColumnSchemaAnalyzerCtor = nullableColumnSchemaAnalyzerType.GetConstructor(new[] { ruleDescriptorType, TSqlModelType, TSqlObjectType });
95+
ConstructorInfo nullableColumnSchemaAnalyzerCtor = nullableColumnSchemaAnalyzerType.GetConstructorSafe(ruleDescriptorType, TSqlModelType, TSqlObjectType);
9696
Guard.IsNotNull(nullableColumnSchemaAnalyzerCtor, nameof(nullableColumnSchemaAnalyzerCtor), "Could not find constructor on NullableColumnSchemaAnalyzer");
9797
ParameterExpression nullableColumnSchemaAnalyzerVariable = Expression.Variable(nullableColumnSchemaAnalyzerType, "nullableColumnSchemaAnalyzer");
9898
Expression nullableColumnSchemaAnalyzerValue = Expression.New(nullableColumnSchemaAnalyzerCtor, ruleDescriptorVariable, dataSchemaModelParameter, modelElementParameter);
@@ -208,7 +208,7 @@ private static void CompileSchemaAnalyzerResultsIterator(Expression resultVariab
208208

209209
// ElementLocation location = new ElementLocation(offset, elementDescriptor.Identifiers, elementAccessor);
210210
Type elementLocationType = typeof(ElementLocation);
211-
ConstructorInfo elementLocationCtor = elementLocationType.GetConstructor(new[] { typeof(int), typeof(IEnumerable<string>), elementAccessorType });
211+
ConstructorInfo elementLocationCtor = elementLocationType.GetConstructorSafe(typeof(int), typeof(IEnumerable<string>), elementAccessorType);
212212
Guard.IsNotNull(elementLocationCtor, nameof(elementLocationCtor), "Could not find constructor on ElementLocation");
213213
Expression identifiersProperty = Expression.Property(elementDescriptorVariable, "Identifiers");
214214
ParameterExpression locationVariable = Expression.Variable(elementLocationType, "location");

src/Dibix.Testing/Configuration/ConfigurationProxyBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Dibix.Testing
99
internal static class ConfigurationProxyBuilder
1010
{
1111
private static readonly Type PropertyInitializationTrackerType = typeof(ConfigurationPropertyInitializationTracker);
12-
private static readonly ConstructorInfo PropertyInitializationTrackerCtor = PropertyInitializationTrackerType.GetConstructor(new[] { typeof(ConfigurationInitializationToken) });
12+
private static readonly ConstructorInfo PropertyInitializationTrackerCtor = PropertyInitializationTrackerType.GetConstructorSafe(typeof(ConfigurationInitializationToken));
1313
private static readonly MethodInfo PropertyInitializationTrackerEnterSectionMethod = PropertyInitializationTrackerType.SafeGetMethod(nameof(ConfigurationPropertyInitializationTracker.EnterSection), new[] { typeof(string) });
1414
private static readonly MethodInfo PropertyInitializationTrackerVerifyMethod = PropertyInitializationTrackerType.SafeGetMethod(nameof(ConfigurationPropertyInitializationTracker.Verify));
1515
private static readonly MethodInfo PropertyInitializationTrackerInitializeMethod = PropertyInitializationTrackerType.SafeGetMethod(nameof(ConfigurationPropertyInitializationTracker.Initialize));
@@ -64,7 +64,7 @@ private static Type BuildProxyType(Type type, ModuleBuilder moduleBuilder = null
6464

6565
// Call base ctor
6666
ctorIL.Emit(OpCodes.Ldarg_0); // this
67-
ctorIL.Emit(OpCodes.Call, type.GetConstructor(Type.EmptyTypes)); // this
67+
ctorIL.Emit(OpCodes.Call, type.GetConstructorSafe(Type.EmptyTypes)); // this
6868
ctorIL.Emit(OpCodes.Nop);
6969

7070
ctorIL.Emit(OpCodes.Nop);
@@ -151,7 +151,7 @@ private static void DefineComplexProperty(PropertyInfo property, ModuleBuilder m
151151
// this.Property = new ConfigurationProxy(initializationToken);
152152
ctorIL.Emit(OpCodes.Ldarg_0); // this
153153
ctorIL.Emit(OpCodes.Ldarg_1); // 'initializationToken'
154-
ctorIL.Emit(OpCodes.Newobj, proxyType.GetConstructor(new[] { typeof(ConfigurationInitializationToken) }));
154+
ctorIL.Emit(OpCodes.Newobj, proxyType.GetConstructorSafe(typeof(ConfigurationInitializationToken)));
155155
ctorIL.Emit(OpCodes.Stfld, underlyingInstanceField);
156156

157157
void GetterBody(ILGenerator getterIL)

src/Dibix.Testing/Http/HttpOfflineServiceFactory.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,11 @@ private static MethodBuilder BuildDelegatedMethod(TypeBuilder typeBuilder, Metho
5959
foreach (ParameterInfo parameter in targetMethod.GetParameters())
6060
parameters.Add(Expression.Parameter(parameter.ParameterType, parameter.Name));
6161

62-
ConstructorInfo httpClientFactoryConstructor = typeof(DefaultHttpClientFactory).GetConstructor(new[] { typeof(HttpClientConfiguration[]) });
63-
if (httpClientFactoryConstructor == null)
64-
throw new InvalidOperationException($"Could not find constructor {typeof(DefaultHttpClientFactory)}({typeof(HttpClientConfiguration)}[])");
65-
62+
ConstructorInfo httpClientFactoryConstructor = typeof(DefaultHttpClientFactory).GetConstructorSafe(typeof(HttpClientConfiguration[]));
6663
Expression offlineClientConfiguration = Expression.New(typeof(OfflineHttpClientConfiguration));
6764
Expression httpClientFactory = Expression.New(httpClientFactoryConstructor, Expression.NewArrayInit(typeof(HttpClientConfiguration), offlineClientConfiguration));
6865
Expression httpAuthorizationProvider = Expression.New(typeof(EmptyHttpAuthorizationProvider));
69-
ConstructorInfo constructor = targetMethod.DeclaringType.GetConstructor(ConstructorSignature);
66+
ConstructorInfo constructor = targetMethod.DeclaringType.GetConstructorSafe(ConstructorSignature);
7067
Expression instance = Expression.New(constructor, httpClientFactory, httpAuthorizationProvider);
7168
Expression call = Expression.Call(instance, targetMethod, parameters);
7269
LambdaExpression lambda = Expression.Lambda(call, parameters);
@@ -96,13 +93,10 @@ private static void BuildDelegatedMethodImplementation(TypeBuilder typeBuilder,
9693

9794
private static void BuildEmptyMethodImplementation(TypeBuilder typeBuilder, MethodInfo methodToImplement)
9895
{
99-
BuildMethodImplementation(typeBuilder, methodToImplement, (parameterTypes, ilGenerator) =>
96+
BuildMethodImplementation(typeBuilder, methodToImplement, (_, ilGenerator) =>
10097
{
10198
Type exceptionType = typeof(NotImplementedException);
102-
ConstructorInfo exceptionCtor = exceptionType.GetConstructor(Type.EmptyTypes);
103-
if (exceptionCtor == null)
104-
throw new InvalidOperationException($"Could not find a parameterless constructor on type: '{exceptionType}'");
105-
99+
ConstructorInfo exceptionCtor = exceptionType.GetConstructorSafe(Type.EmptyTypes);
106100
ilGenerator.Emit(OpCodes.Newobj, exceptionCtor);
107101
ilGenerator.Emit(OpCodes.Throw);
108102
});

src/Dibix.Testing/Http/HttpServiceFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ private static TService CreateServiceInstance<TService>(params KeyValuePair<Type
2424
Type contractType = typeof(TService);
2525
Type implementationType = ResolveImplementationType(contractType);
2626
Type[] constructorSignature = normalizedArgs.Select(x => x.Key).ToArray();
27-
ConstructorInfo constructor = implementationType.GetConstructor(constructorSignature);
27+
ConstructorInfo constructor = implementationType.GetConstructorSafe(constructorSignature);
2828
object[] ctorArgs = normalizedArgs.Select(x => x.Value).ToArray();
2929
TService service = (TService)constructor.Invoke(ctorArgs);
3030
return service;

tests/Dibix.Http.Server.Tests/SqlExceptionFactory.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,18 @@ private static CreateSqlException CompileFactory()
3030
ParameterExpression lineNumberParameter = Expression.Parameter(typeof(int), "lineNumber");
3131
Expression exceptionParameter = Expression.Constant(null, typeof(Exception));
3232

33-
ConstructorInfo sqlErrorConstructor = sqlErrorType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[]
34-
{
35-
infoNumberParameter.Type
33+
ConstructorInfo sqlErrorConstructor = sqlErrorType.GetConstructorSafe
34+
(
35+
BindingFlags.NonPublic | BindingFlags.Instance
36+
, infoNumberParameter.Type
3637
, errorStateParameter.Type
3738
, errorClassParameter.Type
3839
, serverParameter.Type
3940
, errorMessageParameter.Type
4041
, procedureParameter.Type
4142
, lineNumberParameter.Type
4243
, exceptionParameter.Type
43-
}, null);
44+
);
4445

4546
if (sqlErrorConstructor == null)
4647
throw new InvalidOperationException($"Could not find ctor on type '{sqlErrorType}'");

0 commit comments

Comments
 (0)