我试图使用ContextBoundObject和消息接收器将一些方面注入我的代码.
我的问题是我的方面只被调用一次 –
当我打电话时:myFacadee.GetValue(“领带”)
我希望看到我的缓存方面被调用两次
>一次用于’GetValue’方法
>其次是在内部调用的’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"
};
}
}
CacheAttribute:
[AttributeUsage(AttributeTargets.Class)]
public class CacheAttribute : ContextAttribute
{
public CacheAttribute() : base("Security") { }
public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
ctorMsg.ContextProperties.Add(new CacheProperty());
}
}
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"; } }
}
CacheAspect:
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);
}
}
最佳答案 它只被调用一次因为上下文边界只被交叉一次.从实例中调用同一实例不需要任何编组到上下文中,因此您的接收器不用于拦截消息.