如果可能,将 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.
我有两个与使用 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.