/// <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); }
/// <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?.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); serviceProperty.SetParameterBinding( (ServiceParameterBinding) new LazyLoaderParameterBindingFactory(_lazyLoaderParameterBindingFactoryDependencies) .Bind( entityType, typeof(ILazyLoader), nameof(IProxyLazyLoader.LazyLoader))); } // 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]; 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 EntityTypeParameterBinding(), new DependencyInjectionParameterBinding(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); } } } } }