如果可能,将 PostSharp 的合同支持与 AOP 结合使用?

Using PostSharp's Contracts support with AOP if possible?

我有两个与使用 PostSharp 的合同和 AOP 相关的问题:

在 Visual Studio 2015 中运行良好的代码合约的内置支持似乎从 Visual Studio 2017 开始就结束了(不幸的是,我认为).所以我不打算将 MS 的合同与 PostSharp 一起使用(除非可以使用 VS 2017)?

1.) 所以作为替代方案,我在想是否可以使用 PostSharp 提供的 Contracts,并将其与 AOP 结合使用?

我之前一直在使用 PostSharp 的 AOP 支持,以便 "inject" 在我的应用程序中记录日志,以此作为清除横切关注点代码的一种方式,我认为这非常顺利。 如果可能,我想以类似的方式将合约添加到我的代码中吗?

我看到可以像这样添加合同:

public class CustomerModel
{
    public void SetFullName([Required] string firstName, [Required] string lastName)
    {
        this.FullName = firstName + " " + lastName;
    }
}

但是向整个代码库中的每个相关方法追溯添加“[Required]”感觉就像一个拖累:)

PostSharp的AOP好像没有办法和Contracts结合使用?也许这是设计使然,因为我可以想象很难考虑到存在的不同方法签名的所有各种可能性。但是,尽管如此,我只是想确保没有 "magic" 方法使它成为可能,例如使用 AOP 自动添加一个 Contract.Requires(args != null)(但我知道这很难完成,因为您不能将相同的合同应用于原始数据类型等)。

2.) 第二个问题是我找不到 Contract.Ensures(Contract.Result() != null) 或类似的东西?

1) 要一次将 PostSharp 代码契约方面应用于多个目标元素,您可以使用 aspect provider combined with attribute multicasting。例如:

[PSerializable]
public class RequiredProviderAttribute : MethodLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        MethodBase targetMethod = (MethodBase) targetElement;
        ObjectConstruction contract = new ObjectConstruction(typeof(RequiredAttribute));

        foreach (var parameterInfo in targetMethod.GetParameters())
        {
            yield return new AspectInstance(parameterInfo, contract);
        }
    }
}

[RequiredProvider(AttributeTargetMemberAttributes = MulticastAttributes.Public)]
public class Program
{
    static void Main(string[] args)
    {
        Method1(null);
    }

    private static void Method1(object a)
    {
        Method2(a);
    }

    // Contract is applied to the parameter of this method
    public static void Method2(object a)
    {

    }
}

2) PostSharp 代码契约目前仅支持自定义属性语法。但是,要检查 post-conditions,您可以将这些自定义属性应用于 ref 和 out 参数以及方法 return 值。您还可以实现自己的 custom code contracts.