I am trying to use ContextBoundObject and message receivers to inject some aspects into my code.
My problem is that my aspect is called only once - when I call: myFacadee.GetValue("Tie") I would expect my aspect of caching to be called twice
- Once for the <
GetValue method - Secondly, for
GetValues ', which internally is' GetValue '
However, it is called only once for the first call to the GetValue method.
How to modify / fix the following code to make sure that all methods on my " MyFacade " object MyFacade caching aspect. Even if they are called by other methods in the same " MyFacde " object?
Here is a simplified example of what my code looks like:
test application:
class Program { static void Main(string[] args) { var myFacadee = new MyFacade(); System.Console.WriteLine("Value:\t" + myFacadee.GetValue("Tie")); System.Console.ReadLine(); } }
Facade:
[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) {
source share