-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This allows others to build proxies without using internal code. Fixes #14554 #15252 Internal code is still being used for conventions.
- Loading branch information
1 parent
1787752
commit 6139347
Showing
47 changed files
with
1,045 additions
and
947 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// 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.Collections.Generic; | ||
using System.Linq.Expressions; | ||
using JetBrains.Annotations; | ||
using Microsoft.EntityFrameworkCore.Utilities; | ||
|
||
namespace Microsoft.EntityFrameworkCore.Metadata | ||
{ | ||
/// <summary> | ||
/// Defines how to create an entity instance through the binding of EF model properties to, for | ||
/// example, constructor parameters or parameters of a factory method. | ||
/// </summary> | ||
public abstract class ConstructorBinding | ||
{ | ||
/// <summary> | ||
/// Creates a new <see cref="ConstructorBinding" /> instance. | ||
/// </summary> | ||
/// <param name="parameterBindings"> The parameter bindings to use. </param> | ||
protected ConstructorBinding( | ||
[NotNull] IReadOnlyList<ParameterBinding> parameterBindings) | ||
{ | ||
Check.NotNull(parameterBindings, nameof(parameterBindings)); | ||
|
||
ParameterBindings = parameterBindings; | ||
} | ||
|
||
/// <summary> | ||
/// Creates an expression tree that represents creating an entity instance from the given binding | ||
/// information. For example, this might be a <see cref="NewExpression" /> to call a constructor, | ||
/// or a <see cref="MethodCallExpression" /> to call a factory method. | ||
/// </summary> | ||
/// <param name="bindingInfo"> Information needed to create the expression. </param> | ||
/// <returns> The expression tree. </returns> | ||
public abstract Expression CreateConstructorExpression(ParameterBindingInfo bindingInfo); | ||
|
||
/// <summary> | ||
/// The collection of <see cref="ParameterBinding" /> instances used. | ||
/// </summary> | ||
public virtual IReadOnlyList<ParameterBinding> ParameterBindings { get; } | ||
|
||
/// <summary> | ||
/// The type that will be created from the expression tree created for this binding. | ||
/// </summary> | ||
public abstract Type RuntimeType { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// 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.Expressions; | ||
using JetBrains.Annotations; | ||
using Microsoft.EntityFrameworkCore.Storage; | ||
using Microsoft.EntityFrameworkCore.Utilities; | ||
|
||
namespace Microsoft.EntityFrameworkCore.Metadata | ||
{ | ||
/// <summary> | ||
/// Describes the binding of a <see cref="DbContext"/>, which may or may not also have and associated | ||
/// <see cref="IServiceProperty" />, to a parameter in a constructor, factory method, or similar. | ||
/// </summary> | ||
public class ContextParameterBinding : ServiceParameterBinding | ||
{ | ||
/// <summary> | ||
/// Creates a new <see cref="ServiceParameterBinding" /> instance for the given service type. | ||
/// </summary> | ||
/// <param name="contextType"> The <see cref="DbContext"/> CLR type. </param> | ||
/// <param name="serviceProperty"> The associated <see cref="IServiceProperty" />, or null. </param> | ||
public ContextParameterBinding( | ||
[NotNull] Type contextType, | ||
[CanBeNull] IPropertyBase serviceProperty = null) | ||
: base(contextType, contextType, serviceProperty) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an expression tree representing the binding of the value of a property from a | ||
/// materialization expression to a parameter of the constructor, factory method, etc. | ||
/// </summary> | ||
/// <param name="materializationExpression"> The expression representing the materialization context. </param> | ||
/// <param name="entityTypeExpression"> The expression representing the <see cref="IEntityType" /> constant. </param> | ||
/// <returns> The expression tree. </returns> | ||
public override Expression BindToParameter( | ||
Expression materializationExpression, | ||
Expression entityTypeExpression) | ||
{ | ||
Check.NotNull(materializationExpression, nameof(materializationExpression)); | ||
Check.NotNull(entityTypeExpression, nameof(entityTypeExpression)); | ||
|
||
var propertyExpression | ||
= Expression.Property( | ||
materializationExpression, | ||
MaterializationContext.ContextProperty); | ||
|
||
return ServiceType != typeof(DbContext) | ||
? (Expression)Expression.TypeAs(propertyExpression, ServiceType) | ||
: propertyExpression; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
src/EFCore/Metadata/DependencyInjectionMethodParameterBinding.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// 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.Collections.Generic; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
using System.Reflection; | ||
using JetBrains.Annotations; | ||
using Microsoft.EntityFrameworkCore.Utilities; | ||
|
||
namespace Microsoft.EntityFrameworkCore.Metadata | ||
{ | ||
/// <summary> | ||
/// Describes the binding from a method on an EF internal dependency injection service, which may or may not | ||
/// also have and associated <see cref="IServiceProperty" />, to a parameter in a constructor, | ||
/// factory method, or similar. | ||
/// </summary> | ||
public class DependencyInjectionMethodParameterBinding : DependencyInjectionParameterBinding | ||
{ | ||
/// <summary> | ||
/// Creates a new <see cref="DependencyInjectionParameterBinding" /> instance for the given method | ||
/// of the given service type. | ||
/// </summary> | ||
/// <param name="parameterType"> The parameter CLR type. </param> | ||
/// <param name="serviceType"> The service CLR types, as resolved from dependency injection </param> | ||
/// <param name="method"> The method of the service to bind to. </param> | ||
/// <param name="serviceProperty"> The associated <see cref="IServiceProperty" />, or null. </param> | ||
public DependencyInjectionMethodParameterBinding( | ||
[NotNull] Type parameterType, | ||
[NotNull] Type serviceType, | ||
[NotNull] MethodInfo method, | ||
[CanBeNull] IPropertyBase serviceProperty = null) | ||
: base(parameterType, serviceType, serviceProperty) | ||
{ | ||
Check.NotNull(method, nameof(method)); | ||
|
||
Method = method; | ||
} | ||
|
||
/// <summary> | ||
/// The method being bound to, as defined on the dependency injection service interface. | ||
/// </summary> | ||
public virtual MethodInfo Method { get; } | ||
|
||
/// <summary> | ||
/// Creates an expression tree representing the binding of the value of a property from a | ||
/// materialization expression to a parameter of the constructor, factory method, etc. | ||
/// </summary> | ||
/// <param name="materializationExpression"> The expression representing the materialization context. </param> | ||
/// <param name="entityTypeExpression"> The expression representing the <see cref="IEntityType" /> constant. </param> | ||
/// <returns> The expression tree. </returns> | ||
public override Expression BindToParameter( | ||
Expression materializationExpression, | ||
Expression entityTypeExpression) | ||
{ | ||
Check.NotNull(materializationExpression, nameof(materializationExpression)); | ||
Check.NotNull(entityTypeExpression, nameof(entityTypeExpression)); | ||
|
||
var parameters = Method.GetParameters().Select( | ||
(p, i) => Expression.Parameter(p.ParameterType, "param" + i)).ToArray(); | ||
|
||
var serviceVariable = Expression.Variable(ServiceType, "service"); | ||
var delegateVariable = Expression.Variable(ParameterType, "delegate"); | ||
|
||
return Expression.Block( | ||
new[] | ||
{ | ||
serviceVariable, delegateVariable | ||
}, | ||
new List<Expression> | ||
{ | ||
Expression.Assign( | ||
serviceVariable, | ||
base.BindToParameter(materializationExpression, entityTypeExpression)), | ||
Expression.Assign( | ||
delegateVariable, | ||
Expression.Condition( | ||
Expression.ReferenceEqual(serviceVariable, Expression.Constant(null)), | ||
Expression.Constant(null, ParameterType), | ||
Expression.Lambda( | ||
Expression.Call( | ||
serviceVariable, | ||
Method, | ||
parameters), | ||
parameters))), | ||
delegateVariable | ||
}); | ||
} | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
src/EFCore/Metadata/DependencyInjectionParameterBinding.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// 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.Expressions; | ||
using System.Reflection; | ||
using JetBrains.Annotations; | ||
using Microsoft.EntityFrameworkCore.Infrastructure; | ||
using Microsoft.EntityFrameworkCore.Internal; | ||
using Microsoft.EntityFrameworkCore.Storage; | ||
using Microsoft.EntityFrameworkCore.Utilities; | ||
|
||
namespace Microsoft.EntityFrameworkCore.Metadata | ||
{ | ||
/// <summary> | ||
/// Describes the binding from an EF internal dependency injection service, which may or may not | ||
/// also have and associated <see cref="IServiceProperty" />, to a parameter in a constructor, | ||
/// factory method, or similar. | ||
/// </summary> | ||
public class DependencyInjectionParameterBinding : ServiceParameterBinding | ||
{ | ||
private static readonly MethodInfo _getServiceMethod | ||
= typeof(InternalAccessorExtensions).GetMethod(nameof(InternalAccessorExtensions.GetService)); | ||
|
||
/// <summary> | ||
/// Creates a new <see cref="DependencyInjectionParameterBinding" /> instance for the given service type. | ||
/// </summary> | ||
/// <param name="parameterType"> The parameter CLR type. </param> | ||
/// <param name="serviceType"> The service CLR types, as resolved from dependency injection </param> | ||
/// <param name="serviceProperty"> The associated <see cref="IServiceProperty" />, or null. </param> | ||
public DependencyInjectionParameterBinding( | ||
[NotNull] Type parameterType, | ||
[NotNull] Type serviceType, | ||
[CanBeNull] IPropertyBase serviceProperty = null) | ||
: base(parameterType, serviceType, serviceProperty) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an expression tree representing the binding of the value of a property from a | ||
/// materialization expression to a parameter of the constructor, factory method, etc. | ||
/// </summary> | ||
/// <param name="materializationExpression"> The expression representing the materialization context. </param> | ||
/// <param name="entityTypeExpression"> The expression representing the <see cref="IEntityType" /> constant. </param> | ||
/// <returns> The expression tree. </returns> | ||
public override Expression BindToParameter( | ||
Expression materializationExpression, | ||
Expression entityTypeExpression) | ||
{ | ||
Check.NotNull(materializationExpression, nameof(materializationExpression)); | ||
Check.NotNull(entityTypeExpression, nameof(entityTypeExpression)); | ||
|
||
return Expression.Call( | ||
_getServiceMethod.MakeGenericMethod(ServiceType), | ||
Expression.Convert( | ||
Expression.Property( | ||
materializationExpression, | ||
MaterializationContext.ContextProperty), | ||
typeof(IInfrastructure<IServiceProvider>))); | ||
} | ||
} | ||
} |
Oops, something went wrong.