Skip to content

Commit

Permalink
Fixup for #23563
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriySvyryd authored Dec 9, 2020
1 parent 82847c7 commit 2d56999
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 137 deletions.
35 changes: 0 additions & 35 deletions src/EFCore.Abstractions/EntityConfigurationAttribute.cs

This file was deleted.

27 changes: 27 additions & 0 deletions src/EFCore.Abstractions/EntityTypeConfigurationAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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;

namespace Microsoft.EntityFrameworkCore
{
/// <summary>
/// Specifies the configuration type for the entity type.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class EntityTypeConfigurationAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="EntityTypeConfigurationAttribute" /> class.
/// </summary>
/// <param name="entityConfigurationType"> The IEntityTypeConfiguration&lt;&gt; type to use. </param>
public EntityTypeConfigurationAttribute(Type entityConfigurationType)
{
EntityTypeConfigurationType = entityConfigurationType;
}

/// <summary>
/// Type of the entity type configuration.
/// </summary>
public Type EntityTypeConfigurationType { get; }
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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.Linq;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;

namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
/// <summary>
/// A convention that applies the entity type configuration specified in <see cref="EntityTypeConfigurationAttribute" />.
/// </summary>
public class EntityTypeConfigurationEntityTypeAttributeConvention : EntityTypeAttributeConventionBase<EntityTypeConfigurationAttribute>
{
private static readonly MethodInfo _configureMethod = typeof(EntityTypeConfigurationEntityTypeAttributeConvention)
.GetRequiredDeclaredMethod(nameof(Configure));

/// <summary>
/// Creates a new instance of <see cref="EntityTypeConfigurationEntityTypeAttributeConvention" />.
/// </summary>
/// <param name="dependencies"> Parameter object containing dependencies for this convention. </param>
public EntityTypeConfigurationEntityTypeAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies)
: base(dependencies)
{
}

/// <summary>
/// Called after an entity type is added to the model if it has an attribute.
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type. </param>
/// <param name="attribute"> The attribute. </param>
/// <param name="context"> Additional information associated with convention execution. </param>
protected override void ProcessEntityTypeAdded(IConventionEntityTypeBuilder entityTypeBuilder,
EntityTypeConfigurationAttribute attribute,
IConventionContext<IConventionEntityTypeBuilder> context)
{
var entityTypeConfigurationType = attribute.EntityTypeConfigurationType;

if (!entityTypeConfigurationType.GetInterfaces().Any(x =>
x.IsGenericType
&& x.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)
&& x.GenericTypeArguments[0] == entityTypeBuilder.Metadata.ClrType))
{
throw new InvalidOperationException(CoreStrings.InvalidEntityTypeConfigurationAttribute(
entityTypeConfigurationType.ShortDisplayName(), entityTypeBuilder.Metadata.ShortName()));
}

_configureMethod.MakeGenericMethod(entityTypeBuilder.Metadata.ClrType)
.Invoke(null, new object[] { entityTypeBuilder.Metadata, entityTypeConfigurationType });
}

private static void Configure<TEntity>(IConventionEntityType entityType, Type entityTypeConfigurationType)
where TEntity : class
{
var entityTypeBuilder = new EntityTypeBuilder<TEntity>((IMutableEntityType)entityType);
var entityTypeConfiguration = (IEntityTypeConfiguration<TEntity>)Activator.CreateInstance(entityTypeConfigurationType);
entityTypeConfiguration.Configure(entityTypeBuilder);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public virtual ConventionSet CreateConventionSet()
conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention(Dependencies));
conventionSet.EntityTypeAddedConventions.Add(new OwnedEntityTypeAttributeConvention(Dependencies));
conventionSet.EntityTypeAddedConventions.Add(new KeylessEntityTypeAttributeConvention(Dependencies));
conventionSet.EntityTypeAddedConventions.Add(new EntityConfigurationEntityTypeAttributeConvention(Dependencies));
conventionSet.EntityTypeAddedConventions.Add(new EntityTypeConfigurationEntityTypeAttributeConvention(Dependencies));
conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention(Dependencies));
conventionSet.EntityTypeAddedConventions.Add(baseTypeDiscoveryConvention);
conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention);
Expand Down
6 changes: 3 additions & 3 deletions src/EFCore/Properties/CoreStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/EFCore/Properties/CoreStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,8 @@
<data name="InvalidEntityType" xml:space="preserve">
<value>The specified type '{type}' must be a non-interface reference type to be used as an entity type.</value>
</data>
<data name="InvalidEntityTypeConfiguration" xml:space="preserve">
<value>Entity Type Configuration of type {entityTypeConfigurationType} is invalid. The configuration have to implement IEntityTypeConfiguration&lt;{entityType}&gt; Interface.</value>
<data name="InvalidEntityTypeConfigurationAttribute" xml:space="preserve">
<value>The entity type configuration of type '{entityTypeConfigurationType}' is invalid. The configuration specified using EntityTypeConfigurationAttribute has to implement 'IEntityTypeConfiguration&lt;{entityType}&gt;'.</value>
</data>
<data name="InvalidEnumValue" xml:space="preserve">
<value>The value '{value}' provided for argument '{argumentName}' must be a valid value of enum type '{enumType}'.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
public class EntityConfigurationAttributeConventionTest
public class EntityTypeConfigurationAttributeConventionTest
{
[ConditionalFact]
public void EntityConfigurationAttribute_Should_AppliConfiguration_ToEntityType()
public void EntityTypeConfigurationAttribute_should_apply_configuration_to_EntityType()
{
var builder = InMemoryTestHelpers.Instance.CreateConventionBuilder();

Expand All @@ -24,25 +24,32 @@ public void EntityConfigurationAttribute_Should_AppliConfiguration_ToEntityType(
}

[ConditionalFact]
public void EntityConfigurationAttribute_Should_ThrowInvalidOperationException_WhenConfiguration_IsInvalid()
public void EntityTypeConfigurationAttribute_should_throw_when_configuration_is_wrong_type()
{
var builder = InMemoryTestHelpers.Instance.CreateConventionBuilder();

var entityType = (IConventionEntityType)CreateModel().AddEntityType(typeof(User));

Assert.Equal(CoreStrings.InvalidEntityTypeConfiguration(typeof(UserConfiguration), entityType),
Assert.Equal(CoreStrings.InvalidEntityTypeConfigurationAttribute(nameof(UserConfiguration), nameof(User)),
Assert.Throws<InvalidOperationException>(() => builder.Entity<User>()).Message);
}

private static IMutableModel CreateModel()
[ConditionalFact]
public void EntityTypeConfigurationAttribute_should_throw_when_configuration_is_for_wrong_entity_type()
{
var builder = InMemoryTestHelpers.Instance.CreateConventionBuilder();

Assert.Equal(CoreStrings.InvalidEntityTypeConfigurationAttribute(nameof(CustomerConfiguration), nameof(InvalidCustomer)),
Assert.Throws<InvalidOperationException>(() => builder.Entity<InvalidCustomer>()).Message);
}

private static IMutableModel CreateModel()
=> new Model();

private class UserConfiguration
{
}

[EntityConfiguration(typeof(UserConfiguration))]
protected class User
[EntityTypeConfiguration(typeof(UserConfiguration))]
private class User
{
public int Id { get; set; }

Expand All @@ -57,8 +64,16 @@ public void Configure(EntityTypeBuilder<Customer> builder)
}
}

[EntityConfiguration(typeof(CustomerConfiguration))]
protected class Customer
[EntityTypeConfiguration(typeof(CustomerConfiguration))]
private class Customer
{
public int Id { get; set; }

public string Name { get; set; }
}

[EntityTypeConfiguration(typeof(CustomerConfiguration))]
private class InvalidCustomer
{
public int Id { get; set; }

Expand Down

0 comments on commit 2d56999

Please sign in to comment.