Skip to content

Commit

Permalink
Small change to constructor binding convention
Browse files Browse the repository at this point in the history
Issue #10852

Now we pick the constructors with the most number of services, followed by the constructor with the least number of regular properties.
  • Loading branch information
ajcvickers committed Feb 23, 2018
1 parent 9355f64 commit a683153
Show file tree
Hide file tree
Showing 2 changed files with 395 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,53 +37,125 @@ public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder)
if (entityType.ClrType != null
&& !entityType.ClrType.IsAbstract)
{
var foundBinding = (ConstructorBinding)null;
var maxServiceParams = 0;
var minPropertyParams = int.MaxValue;
var foundBindings = new List<ConstructorBinding>();
var bindingFailures = new List<IEnumerable<ParameterInfo>>();

foreach (var constructor in entityType.ClrType.GetTypeInfo()
.DeclaredConstructors
.Where(c => !c.IsStatic)
.OrderByDescending(c => c.GetParameters().Length))
.Where(c => !c.IsStatic))
{
var parameterCount = constructor.GetParameters().Length;

if (foundBinding != null
&& foundBinding.ParameterBindings.Count != parameterCount)
{
break;
}

// Trying to find the constructor with the most service properties
// followed by the least scalar property parameters
if (_bindingFactory.TryBindConstructor(entityType, constructor, out var binding, out var failures))
{
if (foundBinding?.ParameterBindings.Count == parameterCount)
var serviceParamCount = binding.ParameterBindings.OfType<ServiceParameterBinding>().Count();
var propertyParamCount = binding.ParameterBindings.Count - serviceParamCount;

if (serviceParamCount == maxServiceParams
&& propertyParamCount == minPropertyParams)
{
throw new InvalidOperationException(
CoreStrings.ConstructorConflict(
FormatConstructorString(entityType, foundBinding),
FormatConstructorString(entityType, binding)));
foundBindings.Add(binding);
}
else if (serviceParamCount > maxServiceParams)
{
foundBindings.Clear();
foundBindings.Add(binding);

foundBinding = binding;
}
maxServiceParams = serviceParamCount;
minPropertyParams = propertyParamCount;
}
else if (propertyParamCount < minPropertyParams)
{
foundBindings.Clear();
foundBindings.Add(binding);

bindingFailures.Add(failures);
maxServiceParams = serviceParamCount;
minPropertyParams = propertyParamCount;
}
}
else
{
bindingFailures.Add(failures);
}
}

if (foundBinding == null)
if (foundBindings.Count == 0)
{
throw new InvalidOperationException(
CoreStrings.ConstructorNotFound(
entityType.DisplayName(),
string.Join("', '", bindingFailures.SelectMany(f => f).Select(f => f.Name))));
}

if (foundBindings.Count > 1)
{
throw new InvalidOperationException(
CoreStrings.ConstructorConflict(
FormatConstructorString(entityType, foundBindings[0]),
FormatConstructorString(entityType, foundBindings[1])));
}

entityType.Builder.HasAnnotation(
CoreAnnotationNames.ConstructorBinding,
foundBinding,
foundBindings[0],
ConfigurationSource.Convention);
}
}

//foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
//{
// if (entityType.ClrType != null
// && !entityType.ClrType.IsAbstract)
// {
// var foundBinding = (ConstructorBinding)null;
// var bindingFailures = new List<IEnumerable<ParameterInfo>>();

// foreach (var constructor in entityType.ClrType.GetTypeInfo()
// .DeclaredConstructors
// .Where(c => !c.IsStatic)
// .OrderByDescending(c => c.GetParameters().Length))
// {
// var parameterCount = constructor.GetParameters().Length;

// if (foundBinding != null
// && foundBinding.ParameterBindings.Count != parameterCount)
// {
// break;
// }

// if (_bindingFactory.TryBindConstructor(entityType, constructor, out var binding, out var failures))
// {
// if (foundBinding?.ParameterBindings.Count == parameterCount)
// {
// throw new InvalidOperationException(
// CoreStrings.ConstructorConflict(
// FormatConstructorString(entityType, foundBinding),
// FormatConstructorString(entityType, binding)));
// }

// foundBinding = binding;
// }

// bindingFailures.Add(failures);
// }

// if (foundBinding == null)
// {
// throw new InvalidOperationException(
// CoreStrings.ConstructorNotFound(
// entityType.DisplayName(),
// string.Join("', '", bindingFailures.SelectMany(f => f).Select(f => f.Name))));
// }

// entityType.Builder.HasAnnotation(
// CoreAnnotationNames.ConstructorBinding,
// foundBinding,
// ConfigurationSource.Convention);
// }
//}

return modelBuilder;
}

Expand Down
Loading

0 comments on commit a683153

Please sign in to comment.