Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 263
Switch to new EF Core plugin model#672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -9,7 +9,6 @@ | ||
| .idea/ | ||
| .vs/ | ||
| [Bb]in/ | ||
| [Bb]uild/ | ||
| [Oo]bj/ | ||
| [Oo]bj/ | ||
| artifacts/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| using Microsoft.EntityFrameworkCore.Design; | ||
| using Microsoft.EntityFrameworkCore.Storage; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Microsoft.Extensions.DependencyInjection.Extensions; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal; | ||
| namespace Npgsql.EntityFrameworkCore.PostgreSQL.Design.Internal | ||
| { | ||
| public class NpgsqlNetTopologySuiteDesignTimeServices : IDesignTimeServices | ||
| { | ||
| public virtual void ConfigureDesignTimeServices(IServiceCollection serviceCollection) | ||
| => serviceCollection | ||
| .AddSingleton<IRelationalTypeMappingSourcePlugin, NpgsqlNetTopologySuiteTypeMappingSourcePlugin>() | ||
| .TryAddSingleton<INpgsqlNetTopologySuiteOptions, NpgsqlNetTopologySuiteOptions>(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| using GeoAPI; | ||
| using GeoAPI.Geometries; | ||
| using JetBrains.Annotations; | ||
| using Microsoft.EntityFrameworkCore.Infrastructure; | ||
| using Npgsql; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; | ||
| namespace Microsoft.EntityFrameworkCore | ||
| { | ||
| /// <summary> | ||
| /// NetTopologySuite specific extension methods for <see cref="NpgsqlDbContextOptionsBuilder"/>. | ||
| /// </summary> | ||
| public static class NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions | ||
| { | ||
| /// <summary> | ||
| /// Use NetTopologySuite to access SQL Server spatial data. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// The options builder so that further configuration can be chained. | ||
| /// </returns> | ||
| public static NpgsqlDbContextOptionsBuilder UseNetTopologySuite( | ||
| [NotNull] this NpgsqlDbContextOptionsBuilder optionsBuilder, | ||
| ICoordinateSequenceFactory coordinateSequenceFactory = null, | ||
| IPrecisionModel precisionModel = null, | ||
| Ordinates handleOrdinates = Ordinates.None, | ||
| bool geographyAsDefault = false) | ||
| { | ||
| Check.NotNull(optionsBuilder, nameof(optionsBuilder)); | ||
| // TODO: Global-only setup at the ADO.NET level for now, optionally allow per-connection? | ||
| NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite(coordinateSequenceFactory, precisionModel, handleOrdinates, geographyAsDefault); | ||
| var coreOptionsBuilder = ((IRelationalDbContextOptionsBuilderInfrastructure)optionsBuilder).OptionsBuilder; | ||
| var extension = coreOptionsBuilder.Options.FindExtension<NpgsqlNetTopologySuiteOptionsExtension>() | ||
| ?? new NpgsqlNetTopologySuiteOptionsExtension(); | ||
| if (geographyAsDefault) | ||
| extension = extension.WithGeographyDefault(); | ||
| ((IDbContextOptionsBuilderInfrastructure)coreOptionsBuilder).AddOrUpdateExtension(extension); | ||
| return optionsBuilder; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| using JetBrains.Annotations; | ||
| using Microsoft.EntityFrameworkCore.Infrastructure; | ||
| using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; | ||
| using Microsoft.EntityFrameworkCore.Storage; | ||
| using Microsoft.Extensions.DependencyInjection.Extensions; | ||
| using NetTopologySuite; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; | ||
| namespace Microsoft.Extensions.DependencyInjection | ||
| { | ||
| /// <summary> | ||
| /// Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite extension methods for <see cref="IServiceCollection" />. | ||
| /// </summary> | ||
| public static class NpgsqlNetTopologySuiteServiceCollectionExtensions | ||
| { | ||
| /// <summary> | ||
| /// Adds the services required for NetTopologySuite support in the Npgsql provider for Entity Framework. | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| /// </summary> | ||
| /// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param> | ||
| /// <returns>The same service collection so that multiple calls can be chained.</returns> | ||
| public static IServiceCollection AddEntityFrameworkNpgsqlNetTopologySuite( | ||
| [NotNull] this IServiceCollection serviceCollection) | ||
| { | ||
| Check.NotNull(serviceCollection, nameof(serviceCollection)); | ||
| new EntityFrameworkRelationalServicesBuilder(serviceCollection) | ||
| .TryAdd<ISingletonOptions, INpgsqlNetTopologySuiteOptions>(p => p.GetService<INpgsqlNetTopologySuiteOptions>()) | ||
| .TryAddProviderSpecificServices( | ||
| x => x | ||
| .TryAddSingletonEnumerable<IRelationalTypeMappingSourcePlugin, NpgsqlNetTopologySuiteTypeMappingSourcePlugin>() | ||
| .TryAddSingletonEnumerable<IMethodCallTranslatorPlugin, NpgsqlNetTopologySuiteMethodCallTranslatorPlugin>() | ||
| .TryAddSingletonEnumerable<IMemberTranslatorPlugin, NpgsqlNetTopologySuiteMemberTranslatorPlugin>() | ||
| .TryAddSingleton<INpgsqlNetTopologySuiteOptions, NpgsqlNetTopologySuiteOptions>()); | ||
| return serviceCollection; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| using Microsoft.EntityFrameworkCore.Infrastructure; | ||
| namespace Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal | ||
| { | ||
| /// <summary> | ||
| /// Represents options for Npgsql NetTopologySuite that can only be set at the <see cref="IServiceProvider"/> singleton level. | ||
| /// </summary> | ||
| public interface INpgsqlNetTopologySuiteOptions : ISingletonOptions | ||
| { | ||
| /// <summary> | ||
| /// True if geography is to be used by default instead of geometry | ||
| /// </summary> | ||
| bool IsGeographyDefault { get; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Globalization; | ||
| using System.Linq; | ||
| using System.Text; | ||
| using JetBrains.Annotations; | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Microsoft.EntityFrameworkCore.Infrastructure; | ||
| using Microsoft.EntityFrameworkCore.Storage; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Microsoft.Extensions.Primitives; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; | ||
| namespace Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal | ||
| { | ||
| public class NpgsqlNetTopologySuiteOptionsExtension : IDbContextOptionsExtensionWithDebugInfo | ||
| { | ||
| bool _isGeographyDefault; | ||
| string _logFragment; | ||
| public NpgsqlNetTopologySuiteOptionsExtension() {} | ||
| protected NpgsqlNetTopologySuiteOptionsExtension([NotNull] NpgsqlNetTopologySuiteOptionsExtension copyFrom) | ||
| => _isGeographyDefault = copyFrom._isGeographyDefault; | ||
| protected virtual NpgsqlNetTopologySuiteOptionsExtension Clone() => new NpgsqlNetTopologySuiteOptionsExtension(this); | ||
| public virtual bool ApplyServices(IServiceCollection services) | ||
| { | ||
| services.AddEntityFrameworkNpgsqlNetTopologySuite(); | ||
| return false; | ||
| } | ||
| public virtual bool IsGeographyDefault => _isGeographyDefault; | ||
austindrenski marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| public virtual NpgsqlNetTopologySuiteOptionsExtension WithGeographyDefault(bool isGeographyDefault = true) | ||
| { | ||
| var clone = Clone(); | ||
| clone._isGeographyDefault = isGeographyDefault; | ||
| return clone; | ||
| } | ||
| public virtual long GetServiceProviderHashCode() => _isGeographyDefault ? 541 : 0; | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| public virtual void PopulateDebugInfo(IDictionary<string, string> debugInfo) | ||
| { | ||
| Check.NotNull(debugInfo, nameof(debugInfo)); | ||
| debugInfo["NpgsqlNetTopologySuite:" + nameof(IsGeographyDefault)] | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| = (_isGeographyDefault ? 541 : 0).ToString(CultureInfo.InvariantCulture); | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| public virtual void Validate(IDbContextOptions options) | ||
| { | ||
| Check.NotNull(options, nameof(options)); | ||
| var internalServiceProvider = options.FindExtension<CoreOptionsExtension>()?.InternalServiceProvider; | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (internalServiceProvider != null) | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| { | ||
| using (var scope = internalServiceProvider.CreateScope()) | ||
| { | ||
| if (scope.ServiceProvider.GetService<IEnumerable<IRelationalTypeMappingSourcePlugin>>() | ||
| ?.Any(s => s is NpgsqlNetTopologySuiteTypeMappingSourcePlugin) != true) | ||
| { | ||
| throw new InvalidOperationException($"{nameof(NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.UseNetTopologySuite)} requires {nameof(NpgsqlNetTopologySuiteServiceCollectionExtensions.AddEntityFrameworkNpgsqlNetTopologySuite)} to be called on the internal service provider used."); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| [NotNull] | ||
| public virtual string LogFragment | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| { | ||
| get | ||
| { | ||
| if (_logFragment == null) | ||
| { | ||
| var builder = new StringBuilder("using NetTopologySuite"); | ||
| if (_isGeographyDefault) | ||
| builder.Append(" (geography by default)"); | ||
| builder.Append(' '); | ||
| _logFragment = builder.ToString(); | ||
roji marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| return _logFragment; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| using System; | ||
| using Microsoft.EntityFrameworkCore.Infrastructure; | ||
| using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; | ||
| namespace Npgsql.EntityFrameworkCore.PostgreSQL.Internal | ||
| { | ||
| /// <inheritdoc /> | ||
| public class NpgsqlNetTopologySuiteOptions : INpgsqlNetTopologySuiteOptions | ||
| { | ||
| /// <inheritdoc /> | ||
| public bool IsGeographyDefault { get; set; } | ||
| /// <inheritdoc /> | ||
| public void Initialize(IDbContextOptions options) | ||
| { | ||
| var npgsqlNtsOptions = options.FindExtension<NpgsqlNetTopologySuiteOptionsExtension>() ?? new NpgsqlNetTopologySuiteOptionsExtension(); | ||
| IsGeographyDefault = npgsqlNtsOptions.IsGeographyDefault; | ||
| } | ||
| /// <inheritdoc /> | ||
| public void Validate(IDbContextOptions options) {} | ||
| } | ||
| } |
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.