C# 使用Postsharp多次执行方法

C# 使用Postsharp多次执行方法,c#,postsharp,C#,Postsharp,我有一个具有n参数的方法。我想用一个属性来装饰这个方法,该属性保存这些n参数的值。我受到限制,我不能仅提供function(param1,param2)之类的参数就调用此方法,但我可以让函数具有默认参数,并在不更改参数的情况下调用它function(),属性设置为我要在设置这些参数的情况下执行方法: [TestCase] [Parameters(new object[] { 3, 0 })] [Parameters(new object[] { 1, 1 })] [Parameters(new

我有一个具有n参数的方法。我想用一个属性来装饰这个方法,该属性保存这些n参数的值。我受到限制,我不能仅提供
function(param1,param2)
之类的参数就调用此方法,但我可以让函数具有默认参数,并在不更改参数的情况下调用它
function()
,属性设置为我要在设置这些参数的情况下执行方法:

[TestCase]
[Parameters(new object[] { 3, 0 })]
[Parameters(new object[] { 1, 1 })]
[Parameters(new object[] { 4, 4 })]
public void TestParameterized(double x = 0, double y = 0)
{
    Assert.AreEqual(x, y);
}
因为我的参数并不总是双倍的,所以我转移一个对象数组并相应地对其进行强制转换

[Serializable, AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class TestCaseAttribute : OnMethodBoundaryAspect
{
    public TestCaseAttribute()
    {
    }

    public override void OnEntry(MethodExecutionArgs args)
    {
        foreach (object attribute in args.Method.GetCustomAttributes(false))
        {
            if (attribute.GetType() == typeof(ParametersAttribute))
            {
                for (int i = 0; i < args.Arguments.Count; i++)
                {
                    args.Arguments.SetArgument(i, Convert.ToDouble(((ParametersAttribute)attribute).Params[i]));
                }

                base.OnEntry(args);
            }
        }

    }
}
[可序列化,AttributeUsage(AttributeTargets.Method,AllowMultiple=true,Inherited=false)]
公共类TestCaseAttribute:OnMethodBoundaryAspect
{
公共TestCaseAttribute()
{
}
public override void OnEntry(MethodExecutionArgs args)
{
foreach(args.Method.GetCustomAttributes中的对象属性(false))
{
if(attribute.GetType()==typeof(ParametersAttribute))
{
for(int i=0;i
(Parameter属性仅保存给定的参数)

在这里,我将循环使用我拥有的所有参数,这些参数是有效的,并将它们(出于测试目的)转换为双倍。然后,我想“调用”该方法,只要提供属性就可以

不幸的是,与编写方法一样,该方法只执行一次


有人能帮我解决这个问题吗?谢谢大家!

OnMethodBoundaryAspect
只是修饰方法的执行。您需要的是一个拦截执行的
methodinterceptionspect
。见下文

我已经使用
CompileTimeInitialize
方法卸载了部分逻辑来构建时间

我敢将
参数属性
重命名为
参数属性

我还必须添加一个额外的参数以避免递归

class Program
{
    static void Main(string[] args)
    {
        new Program().TestParameterized();
    }

    [TestCase]
    [Arguments(new object[] { 3, 0 })]
    [Arguments(new object[] { 1, 1 })]
    [Arguments(new object[] { 4, 4 })]
    public void TestParameterized(double x = 0, double y = 0, bool recursive = false)
    {
        Console.WriteLine($"{x} == {y}: {x == y}");
    }
}

[Serializable, AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class TestCaseAttribute : MethodInterceptionAspect
{
    private object[][] argumentsCollection;

    public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
    {
        var argumentAttributes = method.GetCustomAttributes(typeof(ArgumentsAttribute)).ToArray();
        argumentsCollection = new object[argumentAttributes.Length][];

        for (int i = 0; i < argumentAttributes.Length; i++)
        {
            object[] givenArguments = ((ArgumentsAttribute)argumentAttributes[i]).Arguments;
            object[] arguments = new object[givenArguments.Length + 1];
            Array.Copy(givenArguments, arguments, givenArguments.Length);
            arguments[givenArguments.Length] = true;
            argumentsCollection[i] = arguments;
        }
    }

    public override void OnInvoke(MethodInterceptionArgs args)
    {
        if ((bool)args.Arguments[args.Arguments.Count - 1])
        {
            args.Proceed();
            return;
        }

        foreach (var arguments in argumentsCollection)
        {
            args.Method.Invoke(args.Instance, arguments);
        }
    }
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
class ArgumentsAttribute : Attribute
{
    public object[] Arguments { get; }

    public ArgumentsAttribute(object[] arguments)
    {
        Arguments = arguments;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
新程序().TestParameterized();
}
[测试用例]
[参数(新对象[]{3,0})]
[参数(新对象[]{1,1})]
[参数(新对象[]{4,4})]
public void TestParameterized(双x=0,双y=0,bool recursive=false)
{
WriteLine($“{x}=={y}:{x==y}”);
}
}
[可序列化,AttributeUsage(AttributeTargets.Method,AllowMultiple=true,Inherited=false)]
公共类TestCaseAttribute:MethodInterceptionSpect
{
私有对象[][]argumentsCollection;
公共重写void CompileTimeInitialize(MethodBase方法,AspectInfo AspectInfo)
{
var argumentAttributes=method.GetCustomAttributes(typeof(ArgumentsAttribute)).ToArray();
argumentsCollection=新对象[argumentAttributes.Length][];
for(int i=0;i
为什么要使用Postsharp重新创建单元测试库?使用现有的单元测试库不是更好吗?请注意,Postsharp会修改被调用的代码,默认情况下不会进行调用。如果您成功了,您仍然需要从某个地方对该方法进行一次调用,这将触发您的三重执行。不幸的是,我正在使用一个框架进行测试,该框架对如何调用函数非常严格,并且没有很多功能,因此目标将是重新实现有助于简化测试开发的功能。