Skip to content

Commit

Permalink
Clean some code and add IOperationProcessor
Browse files Browse the repository at this point in the history
  • Loading branch information
chinadragon0515 committed Jul 11, 2016
1 parent 78717f7 commit 4e9d643
Show file tree
Hide file tree
Showing 19 changed files with 274 additions and 252 deletions.
1 change: 1 addition & 0 deletions src/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
[assembly: SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Microsoft.Restier.Core.QueryableSource.#System.Linq.IQueryProvider.CreateQuery(System.Linq.Expressions.Expression)")]
[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.Restier.Core.Model.ModelContext.#EntitySetTypeMap")]
[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.Restier.Core.Model.ModelContext.#EntityTypeKeyPropertiesMap")]
[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.Restier.Core.Operation.OperationContext.#ParametersValue")]
#endregion

#region CA1801 Unused Parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,26 +80,21 @@ private static string GetAuthorizeMethodName(ChangeSetItem item)
case ChangeSetItemType.DataModification:
DataModificationItem dataModification = (DataModificationItem)item;
string operationName = null;
if (dataModification.ChangeSetItemAction == ChangeSetItemAction.Insert)
if (dataModification.DataModificationItemAction == DataModificationItemAction.Insert)
{
operationName = ConventionBasedChangeSetConstants.AuthorizeMethodDataModificationInsert;
}
else if (dataModification.ChangeSetItemAction == ChangeSetItemAction.Update)
else if (dataModification.DataModificationItemAction == DataModificationItemAction.Update)
{
operationName = ConventionBasedChangeSetConstants.AuthorizeMethodDataModificationUpdate;
}
else if (dataModification.ChangeSetItemAction == ChangeSetItemAction.Remove)
else if (dataModification.DataModificationItemAction == DataModificationItemAction.Remove)
{
operationName = ConventionBasedChangeSetConstants.AuthorizeMethodDataModificationDelete;
}

return operationName + dataModification.EntitySetName;

case ChangeSetItemType.ActionInvocation:
ActionInvocationItem actionItem = (ActionInvocationItem)item;
return ConventionBasedChangeSetConstants.AuthorizeMethodActionInvocationExecute +
actionItem.ActionName;

default:
throw new InvalidOperationException(string.Format(
CultureInfo.InvariantCulture, Resources.InvalidChangeSetEntryType, item.Type));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace Microsoft.Restier.Core.Conventions
{
/// <summary>
/// A convention-based change set item filter.
/// A convention-based change set item processor which calls logic like OnInserting and OnInserted.
/// </summary>
internal class ConventionBasedChangeSetItemProcessor : IChangeSetItemProcessor
{
Expand Down Expand Up @@ -43,7 +43,7 @@ public Task OnProcessingChangeSetItemAsync(
ChangeSetItem item,
CancellationToken cancellationToken)
{
return this.InvokeFilterMethodAsync(
return this.InvokeProcessorMethodAsync(
context, item, ConventionBasedChangeSetConstants.FilterMethodNamePreFilterSuffix);
}

Expand All @@ -53,7 +53,7 @@ public Task OnProcessedChangeSetItemAsync(
ChangeSetItem item,
CancellationToken cancellationToken)
{
return this.InvokeFilterMethodAsync(
return this.InvokeProcessorMethodAsync(
context, item, ConventionBasedChangeSetConstants.FilterMethodNamePostFilterSuffix);
}

Expand All @@ -64,26 +64,21 @@ private static string GetMethodName(ChangeSetItem item, string suffix)
case ChangeSetItemType.DataModification:
DataModificationItem dataModification = (DataModificationItem)item;
string operationName = null;
if (dataModification.ChangeSetItemAction == ChangeSetItemAction.Insert)
if (dataModification.DataModificationItemAction == DataModificationItemAction.Insert)
{
operationName = ConventionBasedChangeSetConstants.FilterMethodDataModificationInsert;
}
else if (dataModification.ChangeSetItemAction == ChangeSetItemAction.Update)
else if (dataModification.DataModificationItemAction == DataModificationItemAction.Update)
{
operationName = ConventionBasedChangeSetConstants.FilterMethodDataModificationUpdate;
}
else if (dataModification.ChangeSetItemAction == ChangeSetItemAction.Remove)
else if (dataModification.DataModificationItemAction == DataModificationItemAction.Remove)
{
operationName = ConventionBasedChangeSetConstants.FilterMethodDataModificationDelete;
}

return operationName + suffix + dataModification.EntitySetName;

case ChangeSetItemType.ActionInvocation:
ActionInvocationItem actionItem = (ActionInvocationItem)item;
return ConventionBasedChangeSetConstants.FilterMethodActionInvocationExecute +
suffix + actionItem.ActionName;

default:
throw new InvalidOperationException(string.Format(
CultureInfo.InvariantCulture, Resources.InvalidChangeSetEntryType, item.Type));
Expand All @@ -98,10 +93,6 @@ private static object[] GetParameters(ChangeSetItem item)
DataModificationItem dataModification = (DataModificationItem)item;
return new object[] { dataModification.Entity };

case ChangeSetItemType.ActionInvocation:
ActionInvocationItem actionItem = (ActionInvocationItem)item;
return actionItem.GetArgumentArray();

default:
throw new InvalidOperationException(string.Format(
CultureInfo.InvariantCulture, Resources.InvalidChangeSetEntryType, item.Type));
Expand All @@ -114,13 +105,13 @@ private static bool ParametersMatch(ParameterInfo[] methodParameters, object[] p
&& !methodParameters.Where((mp, i) => !mp.ParameterType.IsInstanceOfType(parameters[i])).Any();
}

private Task InvokeFilterMethodAsync(
private Task InvokeProcessorMethodAsync(
SubmitContext context,
ChangeSetItem item,
string methodNameSuffix)
{
string methodName = ConventionBasedChangeSetItemProcessor.GetMethodName(item, methodNameSuffix);
object[] parameters = ConventionBasedChangeSetItemProcessor.GetParameters(item);
string methodName = GetMethodName(item, methodNameSuffix);
object[] parameters = GetParameters(item);

MethodInfo method = this.targetType.GetQualifiedMethod(methodName);

Expand All @@ -140,7 +131,7 @@ private Task InvokeFilterMethodAsync(
}

ParameterInfo[] methodParameters = method.GetParameters();
if (ConventionBasedChangeSetItemProcessor.ParametersMatch(methodParameters, parameters))
if (ParametersMatch(methodParameters, parameters))
{
object result = method.Invoke(target, parameters);
Task resultTask = result as Task;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Restier.Core.Operation;

namespace Microsoft.Restier.Core.Conventions
{
/// <summary>
/// A convention-based change set item filter.
/// </summary>
internal class ConventionBasedOperationProcessor : IOperationProcessor
{
private Type targetType;

private ConventionBasedOperationProcessor(Type targetType)
{
Ensure.NotNull(targetType, "targetType");
this.targetType = targetType;
}

/// <inheritdoc/>
public static void ApplyTo(
IServiceCollection services,
Type targetType)
{
Ensure.NotNull(services, "services");
Ensure.NotNull(targetType, "targetType");
services.AddService<IOperationProcessor>(
(sp, next) => new ConventionBasedOperationProcessor(targetType));
}

/// <inheritdoc/>
public Task OnExecutingOperationAsync(
OperationContext context,
CancellationToken cancellationToken)
{
return this.InvokeProcessorMethodAsync(
context, ConventionBasedChangeSetConstants.FilterMethodNamePreFilterSuffix);
}

/// <inheritdoc/>
public Task OnExecutedOperationAsync(
OperationContext context,
CancellationToken cancellationToken)
{
return this.InvokeProcessorMethodAsync(
context, ConventionBasedChangeSetConstants.FilterMethodNamePostFilterSuffix);
}

private static bool ParametersMatch(ParameterInfo[] methodParameters, object[] parameters)
{
return methodParameters.Length == parameters.Length
&& !methodParameters.Where((mp, i) => !mp.ParameterType.IsInstanceOfType(parameters[i])).Any();
}

private Task InvokeProcessorMethodAsync(
OperationContext context,
string methodNameSuffix)
{
string methodName = ConventionBasedChangeSetConstants.FilterMethodActionInvocationExecute +
methodNameSuffix + context.OperationName;
object[] parameters = null;
if (context.ParametersValue != null)
{
context.ParametersValue.ToArray();
}

MethodInfo method = this.targetType.GetQualifiedMethod(methodName);

if (method != null &&
(method.ReturnType == typeof(void) ||
typeof(Task).IsAssignableFrom(method.ReturnType)))
{
object target = null;
if (!method.IsStatic)
{
target = context.GetApiService<ApiBase>();
if (target == null ||
!this.targetType.IsInstanceOfType(target))
{
return Task.WhenAll();
}
}

ParameterInfo[] methodParameters = method.GetParameters();
if (ParametersMatch(methodParameters, parameters))
{
object result = method.Invoke(target, parameters);
Task resultTask = result as Task;
if (resultTask != null)
{
return resultTask;
}
}
}

return Task.WhenAll();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Library;
using Microsoft.Restier.Core.Query;

namespace Microsoft.Restier.Core.Conventions
{
/// <summary>
/// A convention-based query expression filter on entity set.
/// A convention-based query expression processor which will apply OnFilter logic into query expression.
/// </summary>
internal class ConventionBasedEntitySetProcessor : IQueryExpressionProcessor
internal class ConventionBasedQueryExpressionProcessor : IQueryExpressionProcessor
{
private Type targetType;

private ConventionBasedEntitySetProcessor(Type targetType)
private ConventionBasedQueryExpressionProcessor(Type targetType)
{
this.targetType = targetType;
}
Expand All @@ -36,7 +34,7 @@ public static void ApplyTo(
Ensure.NotNull(services, "services");
Ensure.NotNull(targetType, "targetType");
services.AddService<IQueryExpressionProcessor>(
(sp, next) => new ConventionBasedEntitySetProcessor(targetType)
(sp, next) => new ConventionBasedQueryExpressionProcessor(targetType)
{
Inner = next,
});
Expand Down
100 changes: 0 additions & 100 deletions src/Microsoft.Restier.Core/DataSourceStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Restier.Core.Properties;

Expand Down Expand Up @@ -90,104 +89,5 @@ public static TResult GetPropertyValue<TResult>(
{
throw new InvalidOperationException(Resources.DoNotCallDataSourceStubMethodDirectly);
}

/// <summary>
/// Identifies an entity set or results of a call to a function import.
/// TODO reserve for function/action supports
/// </summary>
/// <typeparam name="TElement">
/// The type of the elements in the results.
/// </typeparam>
/// <param name="name">
/// The name of an entity set or function import.
/// </param>
/// <param name="arguments">
/// If <paramref name="name"/> is a function import,
/// the arguments to be passed to the function import.
/// </param>
/// <returns>
/// A representation of the entity set or
/// results of a call to the function import.
/// </returns>
internal static IEnumerable<TElement> Results<TElement>(
string name, params object[] arguments)
{
throw new InvalidOperationException(Resources.DoNotCallDataSourceStubMethodDirectly);
}

/// <summary>
/// Identifies a singleton or result of a
/// call to a singular function import.
/// TODO reserve for function/action supports
/// </summary>
/// <typeparam name="TResult">
/// The type of the result.
/// </typeparam>
/// <param name="name">
/// The name of a singleton or singular function import.
/// </param>
/// <param name="arguments">
/// If <paramref name="name"/> is a singular function import,
/// the arguments to be passed to the singular function import.
/// </param>
/// <returns>
/// A representation of the singleton or result
/// of a call to the singular function import.
/// </returns>
internal static TResult Result<TResult>(
string name, params object[] arguments)
{
throw new InvalidOperationException(Resources.DoNotCallDataSourceStubMethodDirectly);
}

/// <summary>
/// Identifies the results of a call to a function.
/// TODO reserve for function/action supports
/// </summary>
/// <typeparam name="TElement">
/// The type of the elements in the results.
/// </typeparam>
/// <param name="namespaceName">
/// The name of a namespace containing the function.
/// </param>
/// <param name="name">
/// The name of a function.
/// </param>
/// <param name="arguments">
/// The arguments to be passed to the function.
/// </param>
/// <returns>
/// A representation of the results of a call to the function.
/// </returns>
internal static IEnumerable<TElement> Results<TElement>(
string namespaceName, string name, params object[] arguments)
{
throw new InvalidOperationException(Resources.DoNotCallDataSourceStubMethodDirectly);
}

/// <summary>
/// Identifies the result of a call to a singular function.
/// TODO reserve for function/action supports
/// </summary>
/// <typeparam name="TResult">
/// The type of the result.
/// </typeparam>
/// <param name="namespaceName">
/// The name of a namespace containing the singular function.
/// </param>
/// <param name="name">
/// The name of a singular function.
/// </param>
/// <param name="arguments">
/// The arguments to be passed to the singular function.
/// </param>
/// <returns>
/// A representation of the result of a call to the singular function.
/// </returns>
internal static TResult Result<TResult>(
string namespaceName, string name, params object[] arguments)
{
throw new InvalidOperationException(Resources.DoNotCallDataSourceStubMethodDirectly);
}
}
}
Loading

0 comments on commit 4e9d643

Please sign in to comment.