gpt4 book ai didi

c# - 如何在上下文绑定(bind)对象中链接消息接收器(面向方面​​的编程)

转载 作者:行者123 更新时间:2023-11-30 12:34:20 25 4
gpt4 key购买 nike

我正在尝试使用 ContextBoundObject 和消息接收器将某些方面注入(inject)我的代码。

我的问题是我的方面只被调用一次 - 当我打电话时:myFacadee.GetValue("Tie") 我希望看到我的缓存方面被调用两次

  1. 一次用于“GetValue”方法
  2. 其次是在内部调用的“GetValues”'GetValue' 方法

但是,它仅在第一次“GetValue”方法调用时被调用一次。

如何更改/修复以下代码以确保我的“MyFacade”对象上的所有方法都导致调用缓存方面。即使它们被同一“MyFacde”对象中的其他方法调用?

这是我的代码的简化示例:

测试应用:

class Program
{
static void Main(string[] args)
{
var myFacadee = new MyFacade();

System.Console.WriteLine("Value:\t" + myFacadee.GetValue("Tie"));

System.Console.ReadLine();
}
}

门面:

[Cache]
public class MyFacade : ContextBoundObject
{
public string GetValue(string name)
{
return GetValues().FirstOrDefault(x => x.EndsWith(name));
}

public List<string> GetValues()
{
return new List<string>
{
"You asked for a Shirt",
"You asked for a Pants",
"You asked for a Tie"
};
}
}

缓存属性:

[AttributeUsage(AttributeTargets.Class)]
public class CacheAttribute : ContextAttribute
{
public CacheAttribute() : base("Security") { }

public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
ctorMsg.ContextProperties.Add(new CacheProperty());
}
}

缓存属性:

public class CacheProperty : IContextProperty, IContributeObjectSink
{
public IMessageSink GetObjectSink(MarshalByRefObject o, IMessageSink next)
{
return new CacheAspect(next);
}

public void Freeze(Context newContext)
{
// no op
}

public bool IsNewContextOK(Context ctx)
{
var newContextLogProperty = ctx.GetProperty("CacheProperty") as CacheProperty;
if (newContextLogProperty == null)
{
Debug.Assert(false);
return false;
}
return (true);
}

public string Name { get { return "CacheProperty"; } }
}

缓存方面:

internal class CacheAspect : IMessageSink
{
internal CacheAspect(IMessageSink next)
{
_next = next;
}

private readonly IMessageSink _next;

public IMessageSink NextSink
{
get { return _next; }
}

public IMessage SyncProcessMessage(IMessage msg)
{
Preprocess(msg);

var returnMethod = _next.SyncProcessMessage(msg);

return returnMethod;
}

public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
throw new InvalidOperationException();
}

private void Preprocess(IMessage msg)
{
// We only want to process method calls
if (!(msg is IMethodMessage)) return;

var call = msg as IMethodMessage;
var type = Type.GetType(call.TypeName);
var callStr = type.Name + "." + call.MethodName;

var argsString = call.Args.Aggregate((current, next) => current + ", " + next);

Console.WriteLine("Try to get value form cache : {0} for {1}({2})", callStr, call.MethodName, argsString);
}
}

最佳答案

它只被调用一次,因为上下文边界只被跨越一次。从实例内部调用同一实例不需要任何编码到上下文中,因此您的接收器不用于拦截消息。

关于c# - 如何在上下文绑定(bind)对象中链接消息接收器(面向方面​​的编程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7420035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com