Skip to content

Commit

Permalink
Support for overloaded method matching
Browse files Browse the repository at this point in the history
Support for overloaded method matching
  • Loading branch information
hyzx86 committed Oct 7, 2023
2 parents 62c3dfd + 50ac39a commit 629a4f9
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 26 deletions.
4 changes: 2 additions & 2 deletions EasyOC.build/Commons.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

<PropertyGroup>
<!-- after 1.0.3 version depend by tags v* -->
<VersionPrefix>1.0.7</VersionPrefix>
<OrchardCoreVersion>1.6.0</OrchardCoreVersion>
<VersionPrefix>1.0.8</VersionPrefix>
<OrchardCoreVersion>1.7.0</OrchardCoreVersion>
<!--<VersionSuffix>preview</VersionSuffix>-->
<PackageTags>OrcardCore,EasyOC</PackageTags>
<VersionSuffix Condition="'$(VersionSuffix)'!='' AND '$(BuildNumber)' != ''">$(VersionSuffix)</VersionSuffix>
Expand Down
47 changes: 36 additions & 11 deletions src/Modules/EasyOC.ReplaceAction/ActionReplaceOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@ public class ActionReplaceOption
{
public List<ActionReplaceOptionItem> Items { get; set; } = new List<ActionReplaceOptionItem>();

/// <summary>
/// Find first Match
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
public ActionReplaceOptionItem FindOption(MethodInfo method)
{
return Items.OrderBy(x => x.Order).FirstOrDefault(x => x.TargetControllerFullName.Equals(method.DeclaringType.FullName)
&& x.ActionMapping.ContainsKey(method.Name));
}


public List<ActionReplaceOptionItem> AddReplaceOption<TargetNew>(string targetControllerName, IDictionary<string, string> actionMapping, int order = 0)
where TargetNew : class
Expand All @@ -37,16 +26,52 @@ public List<ActionReplaceOptionItem> AddReplaceOption<TargetNew>(string targetCo
return Items;
}


public List<ActionReplaceOptionItem> AddReplaceOption<TargetNew>(string targetControllerName, IDictionary<MethodDescription, MethodDescription> actionMapping)
where TargetNew : class
{
var type = typeof(TargetNew);
var typeInfo = type.GetTypeInfo();
foreach (var kv in actionMapping)
{
var newMethod = kv.Value.Parameters != null ? typeInfo.GetMethod(kv.Value.Name, kv.Value.Parameters) :
typeInfo.GetMethod(kv.Value.Name);
if (newMethod != null)
{
var item = new ActionReplaceOptionItem
{
TargetControllerFullName = targetControllerName,
NewController = type,
TargetMethodDescriptions = new KeyValuePair<MethodDescription, MethodInfo>(kv.Key, newMethod)
};
Items.Add(item);
}
}

return Items;
}

public List<ActionReplaceOptionItem> AddReplaceOption<SourceOld, TargetNew>(IDictionary<string, string> ActionMapping, int order = 0)
where TargetNew : class
{
return AddReplaceOption<TargetNew>(typeof(SourceOld).FullName, ActionMapping, order);
}
}

public class MethodDescription
{
public string Name { get; set; }
/// <summary>
/// 如果未指定参数则不检查
/// </summary>
public Type[] Parameters { get; set; }
}
public class ActionReplaceOptionItem
{
public int Order { get; set; } = 0;
public Dictionary<string, MethodInfo> ActionMapping { get; set; }

public KeyValuePair<MethodDescription, MethodInfo>? TargetMethodDescriptions { get; set; }
public Type NewController { get; set; }
public string TargetControllerFullName { get; set; }

Expand Down
10 changes: 10 additions & 0 deletions src/Modules/EasyOC.ReplaceAction/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,15 @@ public override void ConfigureServices(IServiceCollection services)
nameof(EocAccountController.ExternalLoginCallback),
nameof(EocAccountController.RegisterExternalLogin)
);
//sample 7 Support for overloaded method matching
services.ReplaceAction<EocActivityController>("OrchardCore.Workflows.Controllers.ActivityController",
new List<MethodDescription>()
{
new MethodDescription { Name = "Create", Parameters = new[] { typeof(string), typeof(long), typeof(string) }},
new MethodDescription { Name = "Create", Parameters = new[] { typeof(string), typeof(ActivityEditViewModel) }},
new MethodDescription { Name = "Edit", Parameters = new[] { typeof(long), typeof(string), typeof(string) }},
});
}
```


89 changes: 77 additions & 12 deletions src/Modules/EasyOC.ReplaceAction/ServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace EasyOC.ReplaceAction
Expand Down Expand Up @@ -53,6 +56,27 @@ public static IServiceCollection ReplaceAction<TNew>(this IServiceCollection ser
});
}


public static IServiceCollection ReplaceAction<TNew>(this IServiceCollection services, string targetControllerFullName, IDictionary<MethodDescription, MethodDescription> actionMapping)
where TNew : class
{

return services.ReplaceAction(opt =>
{
opt.AddReplaceOption<TNew>(targetControllerFullName, actionMapping);
});
}

public static IServiceCollection ReplaceAction<TNew>(this IServiceCollection services, string targetControllerFullName, IEnumerable<MethodDescription> actionMapping)
where TNew : class
{

return services.ReplaceAction(opt =>
{
opt.AddReplaceOption<TNew>(targetControllerFullName, actionMapping.ToDictionary(k => k, v => v));
});
}

public static IServiceCollection ReplaceActionByActionNames<TNew>(this IServiceCollection services, string targetControllerFullName, params string[] actionList)
where TNew : class
{
Expand Down Expand Up @@ -85,20 +109,61 @@ public static IServiceProvider UseReplaceAction(this IServiceProvider servicePro
else
{
var actionMethodName = descriptor.MethodInfo.Name;
if (descriptor.ControllerTypeInfo.FullName == item.TargetControllerFullName &&
item.ActionMapping.ContainsKey(actionMethodName)
)
if (descriptor.ControllerTypeInfo.FullName == item.TargetControllerFullName)
{
descriptor.ControllerTypeInfo = item.NewController.GetTypeInfo();
descriptor.MethodInfo = item.ActionMapping[actionMethodName];
if (logger != null && logger.IsEnabled(LogLevel.Debug))
if (item.TargetMethodDescriptions != null)
{
logger.LogDebug("The Action:{action} of controller:{type} is replaced by {newContorller}.{method}",
item.TargetControllerFullName,
actionMethodName,
descriptor.ControllerTypeInfo.FullName,
item.ActionMapping[actionMethodName]
);
var kv = item.TargetMethodDescriptions.Value;
if (kv.Key.Name != actionMethodName)
{
continue;
}
//如果未指定参数 则不检查
if (kv.Key.Parameters != null && kv.Key.Parameters.Length > 0)
{
var parameters = descriptor.MethodInfo.GetParameters();
if (parameters.Length != kv.Key.Parameters.Length)
{
continue;
}
for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i].ParameterType != kv.Key.Parameters[i])
{
continue;
}
}
}
descriptor.ControllerTypeInfo = item.NewController.GetTypeInfo();
descriptor.MethodInfo = kv.Value;

if (logger != null && logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug("The Action:{action} of controller:{type} is replaced by {newContorller}.{method}",
item.TargetControllerFullName,
actionMethodName,
descriptor.ControllerTypeInfo.FullName,
kv.Value.Name
);
}
}
else
{
if (item.ActionMapping.ContainsKey(actionMethodName))
{
descriptor.ControllerTypeInfo = item.NewController.GetTypeInfo();

descriptor.MethodInfo = item.ActionMapping[actionMethodName];
if (logger != null && logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug("The Action:{action} of controller:{type} is replaced by {newContorller}.{method}",
item.TargetControllerFullName,
actionMethodName,
descriptor.ControllerTypeInfo.FullName,
item.ActionMapping[actionMethodName]
);
}
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Modules/EasyOC.ReplaceAction/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Modules;
using System;

namespace EasyOC.ReplaceAction
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static async Task<bool> SendEmailAsync(this Controller controller, string
To = email,
Subject = subject,
Body = body,
IsBodyHtml = true
IsHtmlBody = true
};

var result = await smtpService.SendAsync(message);
Expand Down

0 comments on commit 629a4f9

Please sign in to comment.