Skip to content

Commit

Permalink
Address API Review feedback
Browse files Browse the repository at this point in the history
Part of #15662
  • Loading branch information
bricelam committed Jun 28, 2019
1 parent d13f1b7 commit 4b98b55
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 108 deletions.
6 changes: 3 additions & 3 deletions src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,17 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder,
nameof(IProxyLazyLoader.LazyLoader)));
}

var binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];
var binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding];
if (binding == null)
{
_directBindingConvention.ProcessModelFinalized(modelBuilder, context);
}

binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];
binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding];

entityType.SetAnnotation(
CoreAnnotationNames.ConstructorBinding,
new FactoryMethodConstructorBinding(
new FactoryMethodBinding(
_proxyFactory,
_createLazyLoadingProxyMethod,
new List<ParameterBinding>
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/Infrastructure/ModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ protected virtual void ValidateFieldMapping([NotNull] IModel model, [NotNull] ID
.Concat(entityType.GetDeclaredNavigations())
.Where(p => !p.IsShadowProperty()));

var constructorBinding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];
var constructorBinding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding];

if (constructorBinding != null)
{
Expand Down
38 changes: 22 additions & 16 deletions src/EFCore/Metadata/ConstructorBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,53 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Metadata
{
/// <summary>
/// Defines how to create an entity instance through the binding of EF model properties to, for
/// example, constructor parameters or parameters of a factory method.
/// Defines the binding of parameters to a CLR <see cref="ConstructorInfo" /> for an entity type.
/// </summary>
public abstract class ConstructorBinding
public class ConstructorBinding : InstantiationBinding
{
/// <summary>
/// Creates a new <see cref="ConstructorBinding" /> instance.
/// </summary>
/// <param name="parameterBindings"> The parameter bindings to use. </param>
protected ConstructorBinding(
/// <param name="constructor"> The constructor to use. </param>
/// <param name="parameterBindings"> The parameters to bind. </param>
public ConstructorBinding(
[NotNull] ConstructorInfo constructor,
[NotNull] IReadOnlyList<ParameterBinding> parameterBindings)
: base(parameterBindings)
{
Check.NotNull(parameterBindings, nameof(parameterBindings));
Check.NotNull(constructor, nameof(constructor));

ParameterBindings = parameterBindings;
Constructor = constructor;
}

/// <summary>
/// Creates an expression tree that represents creating an entity instance from the given binding
/// information. For example, this might be a <see cref="NewExpression" /> to call a constructor,
/// or a <see cref="MethodCallExpression" /> to call a factory method.
/// The bound <see cref="ConstructorInfo" />.
/// </summary>
/// <param name="bindingInfo"> Information needed to create the expression. </param>
/// <returns> The expression tree. </returns>
public abstract Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo);
public virtual ConstructorInfo Constructor { get; }

/// <summary>
/// The collection of <see cref="ParameterBinding" /> instances used.
/// Creates a <see cref="NewExpression" /> that represents creating an entity instance using the given
/// constructor.
/// </summary>
public virtual IReadOnlyList<ParameterBinding> ParameterBindings { get; }
/// <param name="bindingInfo"> Information needed to create the expression. </param>
/// <returns> The expression tree. </returns>
public override Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo)
=> Expression.New(
Constructor,
ParameterBindings.Select(b => b.BindToParameter(bindingInfo)));

/// <summary>
/// The type that will be created from the expression tree created for this binding.
/// </summary>
public abstract Type RuntimeType { get; }
public override Type RuntimeType => Constructor.DeclaringType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder,
{
var maxServiceParams = 0;
var minPropertyParams = int.MaxValue;
var foundBindings = new List<ConstructorBinding>();
var foundBindings = new List<InstantiationBinding>();
var bindingFailures = new List<IEnumerable<ParameterInfo>>();

foreach (var constructor in entityType.ClrType.GetTypeInfo()
Expand Down Expand Up @@ -131,7 +131,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder,
}
}

private static string FormatConstructorString(IEntityType entityType, ConstructorBinding binding)
private static string FormatConstructorString(IEntityType entityType, InstantiationBinding binding)
=> entityType.ClrType.ShortDisplayName() +
"(" + string.Join(", ", binding.ParameterBindings.Select(b => b.ParameterType.ShortDisplayName())) + ")";
}
Expand Down
55 changes: 0 additions & 55 deletions src/EFCore/Metadata/DirectConstructorBinding.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// <summary>
/// Defines the binding of parameters to a factory method.
/// </summary>
public class FactoryMethodConstructorBinding : ConstructorBinding
public class FactoryMethodBinding : InstantiationBinding
{
private readonly object _factoryInstance;
private readonly MethodInfo _factoryMethod;

/// <summary>
/// Creates a new <see cref="FactoryMethodConstructorBinding" /> instance for a static factory method.
/// Creates a new <see cref="FactoryMethodBinding" /> instance for a static factory method.
/// </summary>
/// <param name="factoryMethod"> The factory method to bind to. </param>
/// <param name="parameterBindings"> The parameters to use. </param>
/// <param name="runtimeType"> The CLR type of the instance created by the factory method. </param>
public FactoryMethodConstructorBinding(
public FactoryMethodBinding(
[NotNull] MethodInfo factoryMethod,
[NotNull] IReadOnlyList<ParameterBinding> parameterBindings,
[NotNull] Type runtimeType)
Expand All @@ -39,13 +39,13 @@ public FactoryMethodConstructorBinding(
}

/// <summary>
/// Creates a new <see cref="FactoryMethodConstructorBinding" /> instance for a static factory method.
/// Creates a new <see cref="FactoryMethodBinding" /> instance for a static factory method.
/// </summary>
/// <param name="factoryInstance"> The object on which the factory method should be called. </param>
/// <param name="factoryMethod"> The factory method to bind to. </param>
/// <param name="parameterBindings"> The parameters to use. </param>
/// <param name="runtimeType"> The CLR type of the instance created by the factory method. </param>
public FactoryMethodConstructorBinding(
public FactoryMethodBinding(
[NotNull] object factoryInstance,
[NotNull] MethodInfo factoryMethod,
[NotNull] IReadOnlyList<ParameterBinding> parameterBindings,
Expand Down
10 changes: 5 additions & 5 deletions src/EFCore/Metadata/IConstructorBindingFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
{
/// <summary>
/// <para>
/// A factory for finding and creating <see cref="ConstructorBinding" /> instances for
/// A factory for finding and creating <see cref="InstantiationBinding" /> instances for
/// a given CLR constructor.
/// </para>
/// <para>
Expand All @@ -22,19 +22,19 @@ namespace Microsoft.EntityFrameworkCore.Metadata
public interface IConstructorBindingFactory
{
/// <summary>
/// Attempts to create a <see cref="ConstructorBinding" /> for the given <see cref="IEntityType" /> and
/// Attempts to create a <see cref="InstantiationBinding" /> for the given <see cref="IEntityType" /> and
/// <see cref="ConstructorInfo" />
/// </summary>
/// <param name="entityType"> The entity type. </param>
/// <param name="constructor"> The constructor to use. </param>
/// <param name="binding"> The binding, or <c>null</c> if <c>null</c> could be created. </param>
/// <param name="failedBindings"> The parameters that could not be bound. </param>
/// <param name="unboundParameters"> The parameters that could not be bound. </param>
/// <returns> <c>true</c> if a binding was created; <c>false</c> otherwise. </returns>
[ContractAnnotation("=>true, binding:notnull, failedBindings:null; =>false, binding:null, failedBindings:notnull")]
bool TryBindConstructor(
[NotNull] IConventionEntityType entityType,
[NotNull] ConstructorInfo constructor,
[CanBeNull] out ConstructorBinding binding,
[CanBeNull] out IEnumerable<ParameterInfo> failedBindings);
[CanBeNull] out InstantiationBinding binding,
[CanBeNull] out IEnumerable<ParameterInfo> unboundParameters);
}
}
6 changes: 3 additions & 3 deletions src/EFCore/Metadata/IParameterBindingFactories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public interface IParameterBindingFactories
/// Attempts to find a <see cref="IParameterBindingFactory" /> that can bind to a parameter with the
/// given type and name.
/// </summary>
/// <param name="type"> The parameter type. </param>
/// <param name="name"> The parameter name. </param>
/// <param name="parameterType"> The parameter type. </param>
/// <param name="parameterName"> The parameter name. </param>
/// <returns> The found factory, or null if none could be found. </returns>
IParameterBindingFactory FindFactory([NotNull] Type type, [NotNull] string name);
IParameterBindingFactory FindFactory([NotNull] Type parameterType, [NotNull] string parameterName);
}
}
49 changes: 49 additions & 0 deletions src/EFCore/Metadata/InstantiationBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Metadata
{
/// <summary>
/// Defines how to create an entity instance through the binding of EF model properties to, for
/// example, constructor parameters or parameters of a factory method.
/// </summary>
public abstract class InstantiationBinding
{
/// <summary>
/// Creates a new <see cref="InstantiationBinding" /> instance.
/// </summary>
/// <param name="parameterBindings"> The parameter bindings to use. </param>
protected InstantiationBinding(
[NotNull] IReadOnlyList<ParameterBinding> parameterBindings)
{
Check.NotNull(parameterBindings, nameof(parameterBindings));

ParameterBindings = parameterBindings;
}

/// <summary>
/// Creates an expression tree that represents creating an entity instance from the given binding
/// information. For example, this might be a <see cref="NewExpression" /> to call a constructor,
/// or a <see cref="MethodCallExpression" /> to call a factory method.
/// </summary>
/// <param name="bindingInfo"> Information needed to create the expression. </param>
/// <returns> The expression tree. </returns>
public abstract Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo);

/// <summary>
/// The collection of <see cref="ParameterBinding" /> instances used.
/// </summary>
public virtual IReadOnlyList<ParameterBinding> ParameterBindings { get; }

/// <summary>
/// The type that will be created from the expression tree created for this binding.
/// </summary>
public abstract Type RuntimeType { get; }
}
}
10 changes: 5 additions & 5 deletions src/EFCore/Metadata/Internal/ConstructorBindingFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public ConstructorBindingFactory(
public virtual bool TryBindConstructor(
IConventionEntityType entityType,
ConstructorInfo constructor,
out ConstructorBinding binding,
out IEnumerable<ParameterInfo> failedBindings)
out InstantiationBinding binding,
out IEnumerable<ParameterInfo> unboundParameters)
{
IEnumerable<(ParameterInfo Parameter, ParameterBinding Binding)> bindings
= constructor.GetParameters().Select(
Expand All @@ -61,14 +61,14 @@ public virtual bool TryBindConstructor(

if (bindings.Any(b => b.Binding == null))
{
failedBindings = bindings.Where(b => b.Binding == null).Select(b => b.Parameter);
unboundParameters = bindings.Where(b => b.Binding == null).Select(b => b.Parameter);
binding = null;

return false;
}

failedBindings = null;
binding = new DirectConstructorBinding(constructor, bindings.Select(b => b.Binding).ToList());
unboundParameters = null;
binding = new ConstructorBinding(constructor, bindings.Select(b => b.Binding).ToList());

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/EFCore/Metadata/Internal/EntityMaterializerSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public virtual Expression CreateMaterializeExpression(
throw new InvalidOperationException(CoreStrings.CannotMaterializeAbstractType(entityType));
}

var constructorBinding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];
var constructorBinding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding];

if (constructorBinding == null)
{
Expand All @@ -100,7 +100,7 @@ public virtual Expression CreateMaterializeExpression(
throw new InvalidOperationException(CoreStrings.NoParameterlessConstructor(entityType.DisplayName()));
}

constructorBinding = new DirectConstructorBinding(constructorInfo, Array.Empty<ParameterBinding>());
constructorBinding = new ConstructorBinding(constructorInfo, Array.Empty<ParameterBinding>());
}

var bindingInfo = new ParameterBindingInfo(
Expand Down
8 changes: 4 additions & 4 deletions src/EFCore/Metadata/Internal/ParameterBindingFactories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public ParameterBindingFactories(
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IParameterBindingFactory FindFactory(Type type, string name)
=> _parameterBindingFactories.FirstOrDefault(f => f.CanBind(type, name))
?? (_registeredServices.Services.Contains(type)
? new ServiceParameterBindingFactory(type)
public virtual IParameterBindingFactory FindFactory(Type patameterType, string parameterName)
=> _parameterBindingFactories.FirstOrDefault(f => f.CanBind(patameterType, parameterName))
?? (_registeredServices.Services.Contains(patameterType)
? new ServiceParameterBindingFactory(patameterType)
: null);
}
}
2 changes: 1 addition & 1 deletion src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public static bool TryGetMemberInfo(

private static string GetNoFieldErrorMessage(IPropertyBase propertyBase)
{
var constructorBinding = (ConstructorBinding)propertyBase.DeclaringType[CoreAnnotationNames.ConstructorBinding];
var constructorBinding = (InstantiationBinding)propertyBase.DeclaringType[CoreAnnotationNames.ConstructorBinding];

return constructorBinding?.ParameterBindings
.OfType<ServiceParameterBinding>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ private class NoFieldRelated
public NoField NoField { get; set; }
}

private DirectConstructorBinding GetBinding<TEntity>()
private ConstructorBinding GetBinding<TEntity>()
{
var entityType = ((IMutableModel)new Model()).AddEntityType(typeof(TEntity));
entityType.AddProperty(nameof(Blog.Id), typeof(int));
Expand All @@ -768,7 +768,7 @@ private DirectConstructorBinding GetBinding<TEntity>()
var convention = new ConstructorBindingConvention(CreateDependencies());
convention.ProcessModelFinalized(model.Builder, context);

return (DirectConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];
return (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding];
}

private ProviderConventionSetBuilderDependencies CreateDependencies()
Expand Down
Loading

0 comments on commit 4b98b55

Please sign in to comment.