Skip to content
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

Implement entity materialization interception #28274

Merged
merged 2 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/EFCore.Relational/Diagnostics/IDbCommandInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,8 @@ Task CommandFailedAsync(DbCommand command, CommandErrorEventData eventData, Canc
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down
20 changes: 10 additions & 10 deletions src/EFCore.Relational/Diagnostics/IDbConnectionInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ DbConnection ConnectionCreated(ConnectionCreatedEventData eventData, DbConnectio
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand All @@ -103,8 +103,8 @@ InterceptionResult ConnectionOpening(DbConnection connection, ConnectionEventDat
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -149,8 +149,8 @@ Task ConnectionOpenedAsync(DbConnection connection, ConnectionEndEventData event
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand All @@ -170,8 +170,8 @@ InterceptionResult ConnectionClosing(DbConnection connection, ConnectionEventDat
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -230,8 +230,8 @@ InterceptionResult ConnectionDisposing(DbConnection connection, ConnectionEventD
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down
40 changes: 20 additions & 20 deletions src/EFCore.Relational/Diagnostics/IDbTransactionInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ ValueTask<DbTransaction> TransactionUsedAsync(
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -217,8 +217,8 @@ void TransactionCommitted(DbTransaction transaction, TransactionEndEventData eve
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -257,8 +257,8 @@ Task TransactionCommittedAsync(
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -289,8 +289,8 @@ void TransactionRolledBack(DbTransaction transaction, TransactionEndEventData ev
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -329,8 +329,8 @@ Task TransactionRolledBackAsync(
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -360,8 +360,8 @@ void CreatedSavepoint(DbTransaction transaction, TransactionEventData eventData)
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -400,8 +400,8 @@ Task CreatedSavepointAsync(
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -434,8 +434,8 @@ void RolledBackToSavepoint(DbTransaction transaction, TransactionEventData event
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -474,8 +474,8 @@ Task RolledBackToSavepointAsync(
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down Expand Up @@ -505,8 +505,8 @@ void ReleasedSavepoint(DbTransaction transaction, TransactionEventData eventData
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will suppress the operation
/// it was about to perform.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
Expand Down
88 changes: 88 additions & 0 deletions src/EFCore/Diagnostics/IMaterializationInterceptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Diagnostics;

/// <summary>
/// A <see cref="ISingletonInterceptor" /> used to intercept the various parts of object creation and initialization when
/// Entity Framework is creating an object, typically from data returned by a query.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-interceptors">EF Core interceptors</see> for more information and examples.
/// </remarks>
public interface IMaterializationInterceptor : ISingletonInterceptor
{
/// <summary>
/// Called immediately before EF is going to create an instance of an entity. That is, before the constructor has been called.
/// </summary>
/// <param name="materializationData">Contextual information about the materialization happening.</param>
/// <param name="result">
/// Represents the current result if one exists.
/// This value will have <see cref="InterceptionResult{Object}.HasResult" /> set to <see langword="true" /> if some previous
/// interceptor suppressed execution by calling <see cref="InterceptionResult{Object}.SuppressWithResult" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult{Object}.HasResult" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult{Object}.HasResult" /> is <see langword="true" />, then EF will suppress creation of
/// the entity instance and use <see cref="InterceptionResult{Object}.Result" /> instead.
/// An implementation of this method for any interceptor that is not attempting to change the result
/// should return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult<object> CreatingInstance(MaterializationInterceptionData materializationData, InterceptionResult<object> result)
=> result;

/// <summary>
/// Called immediately after EF has created an instance of an entity. That is, after the constructor has been called, but before
/// any properties values not set by the constructor have been set.
/// </summary>
/// <param name="materializationData">Contextual information about the materialization happening.</param>
/// <param name="instance">
/// The entity instance that has been created.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// The entity instance that EF will use.
/// An implementation of this method for any interceptor that is not attempting to change the instance used
/// must return the <paramref name="instance" /> value passed in.
/// </returns>
object CreatedInstance(MaterializationInterceptionData materializationData, object instance)
=> instance;

/// <summary>
/// Called immediately before EF is going to set property values of an entity that has just been created. Note that property values
/// set by the constructor will already have been set.
/// </summary>
/// <param name="materializationData">Contextual information about the materialization happening.</param>
/// <param name="instance">The entity instance for which property values will be set.</param>
/// <param name="result">
/// Represents the current result if one exists.
/// This value will have <see cref="InterceptionResult.IsSuppressed" /> set to <see langword="true" /> if some previous
/// interceptor suppressed execution by calling <see cref="InterceptionResult.Suppress" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will not set any property values.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// setting property values must return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult InitializingInstance(MaterializationInterceptionData materializationData, object instance, InterceptionResult result)
=> result;

/// <summary>
/// Called immediately after EF has set property values of an entity that has just been created.
/// </summary>
/// <param name="materializationData">Contextual information about the materialization happening.</param>
/// <param name="instance">
/// The entity instance that has been created.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// The entity instance that EF will use.
/// An implementation of this method for any interceptor that is not attempting to change the instance used
/// must return the <paramref name="instance" /> value passed in.
/// </returns>
object InitializedInstance(MaterializationInterceptionData materializationData, object instance)
=> instance;
}
Loading