我想知道最好的方法是什么...我有兴趣将PostSharp引入我的一个项目中,但我不确定如何正确地测试标记有属性的类.
例如:
public class hello {
[MyAspectThatDoesSomethingToTheDatabaseWhenThisMethodGetsCalled]
public int omg(string lol) {
//fancy logic in here
}
}
Run Code Online (Sandbox Code Playgroud)
我想测试omg()方法中的逻辑,但是在单元测试中我需要确保不会调用方面,因为实际上没有数据库.
思考?
在询问了关于使用PostSharp实现方面的这个问题之后,我想到我将来可能不得不更新这方面的代码,并且我不想承担之后破坏所有内容的风险.
所以,我开始考虑单元测试.
我的第一个问题是:
考虑单元测试的一个方面是否相关?
我希望答案是"是",但如果没有,我希望得到其他建议.
然后,如果是这样,
如何实现PostSharp方面的单元测试?
只是想知道这些库之间的主要区别是什么,它们在特性和功能上有何不同.
希望获得比我在Google查询中找到的更多信息...
我只是想了解PostSharp,说实话,我认为这太棒了.
但有一件事我很难在PostSharp方面无法完成纯依赖注入(不是服务定位器),也许是因为编译时编织的结果.
来自PHP背景,Symfony有JMSAopBundle,它仍然允许依赖注入它的拦截器.
.Net是否有一些具有相同功能的库?
或者我错过了PostSharp的东西?
好吧,这可能会变得冗长.我想做两件事:
我想通过保存每个调用被路由到的另一个类的实例来创建一个实现接口的类.
我还想拦截所有方法调用并做一些事情.
两个人都做得很好.将它们组合起来似乎只能在一个执行顺序中起作用,而且正如墨菲所说的那样,它是错误的(至少对我而言).
我想注入组成第一,让所有来电的拦截也将拦截那些先前注入.
namespace ConsoleApplication13
{
using System;
using System.Reflection;
using PostSharp;
using PostSharp.Aspects;
using PostSharp.Aspects.Dependencies;
using PostSharp.Extensibility;
[Serializable]
[ProvideAspectRole("COMPOSER")]
public sealed class ComposeAspectAttribute : CompositionAspect
{
[NonSerialized]
private readonly Type interfaceType;
private readonly Type implementationType;
public ComposeAspectAttribute(Type interfaceType, Type implementationType)
{
this.interfaceType = interfaceType;
this.implementationType = implementationType;
}
// Invoked at build time. We return the interface we want to implement.
protected override Type[] GetPublicInterfaces(Type targetType)
{
return new[] { this.interfaceType };
}
// Invoked …Run Code Online (Sandbox Code Playgroud) 我有一些像这样的方面:
public class MyAttribute : OnMethodInvocationAspect
{
public int Offset { get; internal set; }
public MyAttribute(int offset)
{
this.Offset = offset;
}
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
//do some stuff
}
}
Run Code Online (Sandbox Code Playgroud)
现在我正在上课,我将其属性添加到它:
class MyClass
{
[MyAttribute(0x10)]
public int MyProp { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
一切正常.然而现在我想用反射来获得我的偏移; 当我做
typeof(MyClass).GetProperty("MyProp").GetCustomAttributes(true);
Run Code Online (Sandbox Code Playgroud)
它什么都不返回.如何访问原始偏移值(属性上的属性)?
我正在考虑使用Postsharp框架来减轻应用程序方法日志记录的负担.它基本上允许我用日志属性装饰方法,并在编译时将所需的日志代码注入到il中.我喜欢这个解决方案,因为它可以将噪音排除在设计时代码环境之外.任何想法,经验或更好的选择?
我正在阅读有关缓存和记忆的一些文章,以及如何使用委托和泛型轻松实现它.语法非常简单,实现起来非常简单,但我觉得由于重复性,应该可以基于属性生成代码,而不必反复编写相同的管道代码.
假设我们从默认示例开始:
class Foo
{
public int Fibonacci(int n)
{
return n > 1 ? Fibonacci(n-1) + Fibonacci(n-2) : n;
}
}
Run Code Online (Sandbox Code Playgroud)
然后记住这个:
// Let's say we have a utility class somewhere with the following extension method:
// public static Func<TResult> Memoize<TResult>(this Func<TResult> f)
class Foo
{
public Func<int,int> Fibonacci = fib;
public Foo()
{
Fibonacci = Fibonacci.Memoize();
}
public int fib(int n)
{
return n > 1 ? Fibonacci(n-1) + Fibonacci(n-2) : n;
}
}
Run Code Online (Sandbox Code Playgroud)
我想,一旦找到一个匹配其中一个Memoize扩展方法的标记方法,那么只需要创建一个代码生成器就可以更简单.因此,我可以添加一个属性,而不是编写这个管道代码:
class Foo
{ …Run Code Online (Sandbox Code Playgroud) 我正在使用PostSharp版本2.1.6.4(也尝试了最新版本2.1.7.35),有时pdb文件丢失,并且有一个pssym文件.
<?xml version="1.0" encoding="utf-8"?>
<Symbols xmlns="http://schemas.postsharp.org/2.0/symbols">
<Class Class="#1=T:[CrosscuttingLogging]CrosscuttingLogging.Attributes.LogMethodCallStatsAttribute" LimitedLicense="true" />
<Class Class="#2=T:[RequestLimiter]RequestLimiter.RequestCounterAttribute" LimitedLicense="true" />
</Symbols>
Run Code Online (Sandbox Code Playgroud)
我在构建过程中运行procmon,据我所知,postsharp.srv.4.0-x86.exe进程将dll和pdb文件从obj\Debug文件夹移动到obj\Debug\Before-PostSharp文件夹,然后在文件夹中生成一个新的dll obj\Debug,但是没有生成新的pdb文件.
对于我的一些dll(看似随机)会发生这种情况并且似乎不可靠,因为在其他机器上所有pdb文件都是正确生成的.
postsharp ×10
c# ×9
aop ×6
.net ×2
unit-testing ×2
attributes ×1
logging ×1
msbuild ×1
nunit ×1
pdb ×1