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

时间:2018-03-24 05:27:03

标签: c# aop postsharp code-contracts

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

与Visual Studio 2015配合使用的代码合同的内置支持似乎已从Visual Studio 2017开始(不幸的是在我看来)。所以我不打算在PostSharp中使用MS的合同(除非可以使用VS 2017)?

1。)作为替代方案,我在考虑是否可以使用PostSharp提供的合同,并将其与AOP结合使用?

我之前一直在使用PostSharp的AOP支持,以便注入"记录我的应用程序,以清除跨领域问题的代码,我认为这非常好。 如果可能的话,我想以类似的方式将合同添加到我的代码中?

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

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

但要追溯添加" [必需]"对整个代码库中的每个相关方法感觉就像一个拖动:)

似乎没有办法将PostSharp的AOP与合同结合使用?也许这是设计,因为我可以想象很难考虑存在的不同方法签名的各种可能性。但是,我只是想确保没有"魔法"使它成为可能的方式,例如使用AOP自动添加Contract.Requires(args!= null)(但我知道很难完成,因为你不能将相同的契约应用于原始数据类型等。)

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

1 个答案:

答案 0 :(得分:0)

1)要将PostSharp代码合同方面同时应用于多个目标元素,您可以将aspect providerattribute 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代码合约目前仅支持自定义属性语法。但是,要检查后置条件,可以将这些自定义属性应用于ref和out参数以及方法返回值。您还可以实现自己的custom code contracts