public void Throws_if_sealed_class() { using var context = new NeweyContextN1(); Assert.Equal( ProxiesStrings.ItsASeal(nameof(McLarenMp418)), Assert.Throws <InvalidOperationException>( () => context.Model).Message); }
public void Throws_if_sealed_class() { using var context = new ChangeContext <ChangeSealedEntity>(); Assert.Equal( ProxiesStrings.ItsASeal(nameof(ChangeSealedEntity)), Assert.Throws <InvalidOperationException>( () => context.Model).Message); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) { if (_options?.UseLazyLoadingProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { if (entityType.ClrType != null && !entityType.ClrType.IsAbstract) { if (entityType.ClrType.IsSealed) { throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName())); } var binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) { _directBindingConvention.Apply(modelBuilder); } binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; entityType[CoreAnnotationNames.ConstructorBinding] = RewriteToFactoryBinding(binding); foreach (var navigation in entityType.GetNavigations()) { if (navigation.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldNavigation(navigation.Name, entityType.DisplayName())); } if (!navigation.PropertyInfo.GetMethod.IsVirtual) { throw new InvalidOperationException( ProxiesStrings.NonVirtualNavigation(navigation.Name, entityType.DisplayName())); } navigation.SetPropertyAccessMode(PropertyAccessMode.Field); } } } } return(modelBuilder); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) { if (_options?.UseLazyLoadingProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { if (entityType.ClrType?.IsAbstract == false) { if (entityType.ClrType.IsSealed) { throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName())); } var proxyType = _proxyFactory.CreateLazyLoadingProxyType(entityType); foreach (var conflictingProperty in entityType.GetDerivedTypes() .SelectMany(e => e.GetDeclaredServiceProperties().Where(p => p.ClrType == typeof(ILazyLoader))) .ToList()) { conflictingProperty.DeclaringEntityType.RemoveServiceProperty(conflictingProperty.Name); } var serviceProperty = entityType.GetServiceProperties().FirstOrDefault(e => e.ClrType == typeof(ILazyLoader)); if (serviceProperty == null) { serviceProperty = entityType.AddServiceProperty(_lazyLoaderProperty, ConfigurationSource.Convention); serviceProperty.SetParameterBinding( (ServiceParameterBinding) new LazyLoaderParameterBindingFactory().Bind( entityType, typeof(ILazyLoader), nameof(IProxyLazyLoader.LazyLoader))); } var binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) { _directBindingConvention.Apply(modelBuilder); } binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; entityType[CoreAnnotationNames.ConstructorBinding] = new FactoryMethodConstructorBinding( _proxyFactory, _createLazyLoadingProxyMethod, new List <ParameterBinding> { new EntityTypeParameterBinding(), new DefaultServiceParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader), serviceProperty), new ObjectArrayParameterBinding(binding.ParameterBindings) }, proxyType); foreach (var navigation in entityType.GetNavigations()) { if (navigation.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldNavigation(navigation.Name, entityType.DisplayName())); } if (!navigation.PropertyInfo.GetMethod.IsVirtual) { throw new InvalidOperationException( ProxiesStrings.NonVirtualNavigation(navigation.Name, entityType.DisplayName())); } navigation.SetPropertyAccessMode(PropertyAccessMode.Field); } } } } return(modelBuilder); }
public virtual void ProcessModelFinalizing( IConventionModelBuilder modelBuilder, IConventionContext <IConventionModelBuilder> context) { if (_options?.UseProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { var clrType = entityType.ClrType; if (!clrType.IsAbstract) { if (clrType.IsSealed) { throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName())); } var proxyType = _proxyFactory.CreateProxyType(_options, (IEntityType)entityType); // WARNING: This code is EF internal; it should not be copied. See #10789 #14554 #pragma warning disable EF1001 // Internal EF Core API usage. var binding = (InstantiationBinding?)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) { _directBindingConvention.ProcessModelFinalizing(modelBuilder, context); } binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding] !; UpdateConstructorBindings(CoreAnnotationNames.ConstructorBinding, binding); binding = (InstantiationBinding?)entityType[CoreAnnotationNames.ServiceOnlyConstructorBinding]; if (binding != null) { UpdateConstructorBindings(CoreAnnotationNames.ServiceOnlyConstructorBinding, binding); } #pragma warning restore EF1001 // Internal EF Core API usage. foreach (var navigationBase in entityType.GetDeclaredNavigations() .Concat <IConventionNavigationBase>(entityType.GetDeclaredSkipNavigations())) { if (navigationBase.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldProperty(navigationBase.Name, entityType.DisplayName())); } if (_options.UseChangeTrackingProxies && navigationBase.PropertyInfo.SetMethod?.IsReallyVirtual() == false) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(navigationBase.Name, entityType.DisplayName())); } if (_options.UseLazyLoadingProxies) { if (!navigationBase.PropertyInfo.GetMethod.IsReallyVirtual() && (!(navigationBase is INavigation navigation && navigation.ForeignKey.IsOwnership))) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(navigationBase.Name, entityType.DisplayName())); } navigationBase.SetPropertyAccessMode(PropertyAccessMode.Field); } } if (_options.UseChangeTrackingProxies) { var indexerChecked = false; foreach (var property in entityType.GetDeclaredProperties() .Where(p => !p.IsShadowProperty())) { if (property.IsIndexerProperty()) { if (!indexerChecked) { indexerChecked = true; if (!property.PropertyInfo !.SetMethod.IsReallyVirtual()) { if (clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(Dictionary <,>) && clrType.GenericTypeArguments[0] == typeof(string)) { if (entityType.GetProperties().Any(p => !p.IsPrimaryKey())) { throw new InvalidOperationException( ProxiesStrings.DictionaryCannotBeProxied( clrType.ShortDisplayName(), entityType.DisplayName(), typeof(IDictionary <,>).MakeGenericType(clrType.GenericTypeArguments) .ShortDisplayName())); } } else { throw new InvalidOperationException( ProxiesStrings.NonVirtualIndexerProperty(entityType.DisplayName())); } } } } else { if (property.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldProperty(property.Name, entityType.DisplayName())); } if (property.PropertyInfo.SetMethod?.IsReallyVirtual() == false) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(property.Name, entityType.DisplayName())); } } } } void UpdateConstructorBindings(string bindingAnnotationName, InstantiationBinding binding) { if (_options.UseLazyLoadingProxies) { foreach (var conflictingProperty in entityType.GetDerivedTypes() .SelectMany(e => e.GetDeclaredServiceProperties().Where(p => p.ClrType == typeof(ILazyLoader))) .ToList()) { conflictingProperty.DeclaringEntityType.RemoveServiceProperty(conflictingProperty.Name); } var serviceProperty = entityType.GetServiceProperties() .FirstOrDefault(e => e.ClrType == typeof(ILazyLoader)); if (serviceProperty == null) { serviceProperty = entityType.AddServiceProperty(_lazyLoaderProperty); serviceProperty.SetParameterBinding( (ServiceParameterBinding) new LazyLoaderParameterBindingFactory( _lazyLoaderParameterBindingFactoryDependencies) .Bind( entityType, typeof(ILazyLoader), nameof(IProxyLazyLoader.LazyLoader))); } entityType.SetAnnotation( bindingAnnotationName, new FactoryMethodBinding( _proxyFactory, _createLazyLoadingProxyMethod, new List <ParameterBinding> { new ContextParameterBinding(typeof(DbContext)), new EntityTypeParameterBinding(), new DependencyInjectionParameterBinding( typeof(ILazyLoader), typeof(ILazyLoader), (IPropertyBase)serviceProperty), new ObjectArrayParameterBinding(binding.ParameterBindings) }, proxyType)); } else { entityType.SetAnnotation( bindingAnnotationName, new FactoryMethodBinding( _proxyFactory, _createProxyMethod, new List <ParameterBinding> { new ContextParameterBinding(typeof(DbContext)), new EntityTypeParameterBinding(), new ObjectArrayParameterBinding(binding.ParameterBindings) }, proxyType)); } } } } } }
/// <summary> /// Called after a model is finalized. /// </summary> /// <param name="modelBuilder"> The builder for the model. </param> /// <param name="context"> Additional information associated with convention execution. </param> public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext <IConventionModelBuilder> context) { if (_options?.UseProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { if (entityType.ClrType?.IsAbstract == false) { if (entityType.ClrType.IsSealed) { throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName())); } var proxyType = _proxyFactory.CreateProxyType(_options, entityType); // WARNING: This code is EF internal; it should not be copied. See #10789 #14554 var binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) { _directBindingConvention.ProcessModelFinalized(modelBuilder, context); } // WARNING: This code is EF internal; it should not be copied. See #10789 #14554 binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (_options.UseLazyLoadingProxies) { foreach (var conflictingProperty in entityType.GetDerivedTypes() .SelectMany(e => e.GetDeclaredServiceProperties().Where(p => p.ClrType == typeof(ILazyLoader))) .ToList()) { conflictingProperty.DeclaringEntityType.RemoveServiceProperty(conflictingProperty.Name); } var serviceProperty = entityType.GetServiceProperties().FirstOrDefault(e => e.ClrType == typeof(ILazyLoader)); if (serviceProperty == null) { serviceProperty = entityType.AddServiceProperty(_lazyLoaderProperty); serviceProperty.SetParameterBinding( (ServiceParameterBinding) new LazyLoaderParameterBindingFactory( _lazyLoaderParameterBindingFactoryDependencies) .Bind( entityType, typeof(ILazyLoader), nameof(IProxyLazyLoader.LazyLoader))); } entityType.SetAnnotation( // WARNING: This code is EF internal; it should not be copied. See #10789 #14554 CoreAnnotationNames.ConstructorBinding, new FactoryMethodBinding( _proxyFactory, _createLazyLoadingProxyMethod, new List <ParameterBinding> { new DependencyInjectionParameterBinding(typeof(IDbContextOptions), typeof(IDbContextOptions)), new EntityTypeParameterBinding(), new DependencyInjectionParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader), serviceProperty), new ObjectArrayParameterBinding(binding.ParameterBindings) }, proxyType)); } else { entityType.SetAnnotation( // WARNING: This code is EF internal; it should not be copied. See #10789 #14554 CoreAnnotationNames.ConstructorBinding, new FactoryMethodBinding( _proxyFactory, _createProxyMethod, new List <ParameterBinding> { new DependencyInjectionParameterBinding(typeof(IDbContextOptions), typeof(IDbContextOptions)), new EntityTypeParameterBinding(), new ObjectArrayParameterBinding(binding.ParameterBindings) }, proxyType)); foreach (var prop in entityType.GetProperties().Where(p => !p.IsShadowProperty())) { if (prop.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldProperty(prop.Name, entityType.DisplayName())); } if (prop.PropertyInfo.SetMethod?.IsVirtual == false) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(prop.Name, entityType.DisplayName())); } } } foreach (var navigation in entityType.GetNavigations()) { if (navigation.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldProperty(navigation.Name, entityType.DisplayName())); } if (_options.UseChangeDetectionProxies && navigation.PropertyInfo.SetMethod?.IsVirtual == false) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(navigation.Name, entityType.DisplayName())); } if (_options.UseLazyLoadingProxies) { if (!navigation.PropertyInfo.GetMethod.IsVirtual) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(navigation.Name, entityType.DisplayName())); } navigation.SetPropertyAccessMode(PropertyAccessMode.Field); } } } } } }
/// <inheritdoc /> public virtual void ProcessModelFinalizing( IConventionModelBuilder modelBuilder, IConventionContext <IConventionModelBuilder> context) { if (_options?.UseProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { var clrType = entityType.ClrType; if (clrType.IsAbstract) { continue; } if (clrType.IsSealed) { throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName())); } var proxyType = _proxyFactory.CreateProxyType(_options, entityType); // WARNING: This code is EF internal; it should not be copied. See #10789 #14554 #pragma warning disable EF1001 // Internal EF Core API usage. var binding = ((EntityType)entityType).ConstructorBinding; if (binding == null) { _directBindingConvention.ProcessModelFinalizing(modelBuilder, context); binding = ((EntityType)entityType).ConstructorBinding !; } ((EntityType)entityType).SetConstructorBinding( UpdateConstructorBindings(entityType, proxyType, binding), ConfigurationSource.Convention); binding = ((EntityType)entityType).ServiceOnlyConstructorBinding; if (binding != null) { ((EntityType)entityType).SetServiceOnlyConstructorBinding( UpdateConstructorBindings(entityType, proxyType, binding), ConfigurationSource.Convention); } #pragma warning restore EF1001 // Internal EF Core API usage. foreach (var navigationBase in entityType.GetDeclaredNavigations() .Concat <IConventionNavigationBase>(entityType.GetDeclaredSkipNavigations())) { if (navigationBase.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldProperty(navigationBase.Name, entityType.DisplayName())); } if (_options.UseChangeTrackingProxies && navigationBase.PropertyInfo.SetMethod?.IsReallyVirtual() == false) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(navigationBase.Name, entityType.DisplayName())); } if (_options.UseLazyLoadingProxies) { if (!navigationBase.PropertyInfo.GetMethod !.IsReallyVirtual() && (!(navigationBase is INavigation navigation && navigation.ForeignKey.IsOwnership))) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(navigationBase.Name, entityType.DisplayName())); } navigationBase.SetPropertyAccessMode(PropertyAccessMode.Field); } } if (_options.UseChangeTrackingProxies) { var indexerChecked = false; foreach (var property in entityType.GetDeclaredProperties() .Where(p => !p.IsShadowProperty())) { if (property.IsIndexerProperty()) { if (!indexerChecked) { indexerChecked = true; if (!property.PropertyInfo !.SetMethod !.IsReallyVirtual()) { if (clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(Dictionary <,>) && clrType.GenericTypeArguments[0] == typeof(string)) { if (entityType.GetProperties().Any(p => !p.IsPrimaryKey())) { throw new InvalidOperationException( ProxiesStrings.DictionaryCannotBeProxied( clrType.ShortDisplayName(), entityType.DisplayName(), typeof(IDictionary <,>).MakeGenericType(clrType.GenericTypeArguments) .ShortDisplayName())); } } else { throw new InvalidOperationException( ProxiesStrings.NonVirtualIndexerProperty(entityType.DisplayName())); } } } } else { if (property.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldProperty(property.Name, entityType.DisplayName())); } if (property.PropertyInfo.SetMethod?.IsReallyVirtual() == false) { throw new InvalidOperationException( ProxiesStrings.NonVirtualProperty(property.Name, entityType.DisplayName())); } } } } } } }