传递只有 PostSharp 可以看到的 class 对象
Passing a class object that only PostSharp can see
我不确定这是否可行。
我有一个从客户端 api 到服务 api 的方法调用(在两个不同位置的两个不同项目),我希望 post sharp 拦截。调用来自客户端并且 postsharp 在服务中
service.GetLogin(username)
这里的关键是我需要传递一个将在 postsharp onentry 方法中显示的授权对象
public class Authorization
{
public string client_id { get; set; }
public string client_secret { get; set; }
public string access_token { get; set; }
public string token_type { get; set; }
public string expires_in { get; set; }
}
var auth = new Authorization();
auth.client_id = "xyz";
auth.client_secret = "abc"
并在 post尖
[Serializable]
public class LoggingAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
//I need the object to show up here
}
}
问题:
我不想在每个方法调用中都传递这个对象,因为我有 1000 多个方法。有没有办法将该授权对象附加到每个调用,以便 postsharp 可以看到它而无需执行类似这样的操作
service.GetLogin(username, auth);
service.Foo(auth)
service.Bar(auth);
service.xyz(auth);
services.abc(auth);
您能想象仅将这个对象添加到 1000 多个方法中吗?
PostSharp 无法直接使用来自调用站点的数据,因为它需要向方法添加实际参数(或发出新的重载)。这在理论上可以使用 low-level SDK,但难以维护且实施成本高。
实现此目的的最佳方法是使用 AsyncLocal<T>
,它允许您将数据存储在 ExecutionContext
。
public class AuthorizationProvider
{
private static AsyncLocal<Authorization> state = new AsyncLocal<Authorization>();
public Authorization Current { get => state.Value; set => state.Value = value; }
}
授权有效的代码将是:
Authorization authorization = ... ;
try
{
AuthorizationProvider.Current = authorization;
// your logic.
}
finally
{
AuthorizationProvider.Current = null;
}
然后可以从OnEntry中读取授权对象:
[Serializable]
public class LoggingAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (!(AuthorizationProvider.Current?.IsValid ?? false))
{
...
}
}
}
你也可以将当前Authorization的setting/unsetting包裹在一个IDisposable中,这样你就可以使用using
语句。
在 AsyncLocal 中分配的值集存储在执行上下文中,因此通过异步调用流动。存储在执行上下文中的值,在您删除上面 finally 块中的值后可能会被捕获和使用。 See more here.
我不确定这是否可行。
我有一个从客户端 api 到服务 api 的方法调用(在两个不同位置的两个不同项目),我希望 post sharp 拦截。调用来自客户端并且 postsharp 在服务中
service.GetLogin(username)
这里的关键是我需要传递一个将在 postsharp onentry 方法中显示的授权对象
public class Authorization
{
public string client_id { get; set; }
public string client_secret { get; set; }
public string access_token { get; set; }
public string token_type { get; set; }
public string expires_in { get; set; }
}
var auth = new Authorization();
auth.client_id = "xyz";
auth.client_secret = "abc"
并在 post尖
[Serializable]
public class LoggingAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
//I need the object to show up here
}
}
问题: 我不想在每个方法调用中都传递这个对象,因为我有 1000 多个方法。有没有办法将该授权对象附加到每个调用,以便 postsharp 可以看到它而无需执行类似这样的操作
service.GetLogin(username, auth);
service.Foo(auth)
service.Bar(auth);
service.xyz(auth);
services.abc(auth);
您能想象仅将这个对象添加到 1000 多个方法中吗?
PostSharp 无法直接使用来自调用站点的数据,因为它需要向方法添加实际参数(或发出新的重载)。这在理论上可以使用 low-level SDK,但难以维护且实施成本高。
实现此目的的最佳方法是使用 AsyncLocal<T>
,它允许您将数据存储在 ExecutionContext
。
public class AuthorizationProvider
{
private static AsyncLocal<Authorization> state = new AsyncLocal<Authorization>();
public Authorization Current { get => state.Value; set => state.Value = value; }
}
授权有效的代码将是:
Authorization authorization = ... ;
try
{
AuthorizationProvider.Current = authorization;
// your logic.
}
finally
{
AuthorizationProvider.Current = null;
}
然后可以从OnEntry中读取授权对象:
[Serializable]
public class LoggingAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (!(AuthorizationProvider.Current?.IsValid ?? false))
{
...
}
}
}
你也可以将当前Authorization的setting/unsetting包裹在一个IDisposable中,这样你就可以使用using
语句。
在 AsyncLocal 中分配的值集存储在执行上下文中,因此通过异步调用流动。存储在执行上下文中的值,在您删除上面 finally 块中的值后可能会被捕获和使用。 See more here.