2016-07-13 5 views
0

У меня есть класс в SampleClassLibrary, называемый DataLayerClass.This класс имеет атрибут для целей трассировки.Аспектно-ориентированное программирование в C#

[Tracing] 
public class DataLayerClass:ContextBoundObject 
{ 
    public string DataLayerMethod() 
    { 
     return "Hi"; 
    } 
} 

Этот атрибут реализован с использованием AOP.The кода будет выглядеть следующим образом:

internal class TracingAspect : IMessageSink 
{ 
    internal TracingAspect(IMessageSink next) 
    { 
     m_next = next; 
    } 

    #region Private Vars 
    private IMessageSink m_next; 
    private String m_typeAndName; 
    #endregion // Private Vars 

    #region IMessageSink implementation 
    public IMessageSink NextSink 
    { 
     get { return m_next; } 
    } 

    public IMessage SyncProcessMessage(IMessage msg) 
    { 
     Preprocess(msg); 
     IMessage returnMethod = m_next.SyncProcessMessage(msg); 
     PostProcess(msg, returnMethod); 
     return returnMethod; 
    } 

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

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

     IMethodMessage call = msg as IMethodMessage; 
     Type type = Type.GetType(call.TypeName); 
     m_typeAndName = type.Name + "." + call.MethodName; 
     NLogging.Trace("PreProcessing: " + m_typeAndName + "("); 

     // Loop through the [in] parameters 
     for (int i = 0; i < call.ArgCount; ++i) 
     { 
      if (i > 0) Console.Write(", "); 
      Console.Write(call.GetArgName(i) + " = " + call.GetArg(i)); 
     } 
     NLogging.Trace(")"); 
    } 

    private void PostProcess(IMessage msg, IMessage msgReturn) 
    { 
     // We only want to process method return calls 
     if (!(msg is IMethodMessage) || 
      !(msgReturn is IMethodReturnMessage)) return; 

     IMethodReturnMessage retMsg = (IMethodReturnMessage)msgReturn; 
     NLogging.Trace("PostProcessing: "); 
     Exception e = retMsg.Exception; 
     if (e != null) 
     { 
      NLogging.Trace("Exception was thrown: " + e); 
      return; 
     } 

     // Loop through all the [out] parameters 
     NLogging.Trace(m_typeAndName + "("); 
     if (retMsg.OutArgCount > 0) 
     { 
      NLogging.Trace("out parameters["); 
      for (int i = 0; i < retMsg.OutArgCount; ++i) 
      { 
       if (i > 0) Console.Write(", "); 
       Console.Write(retMsg.GetOutArgName(i) + " = " + 
           retMsg.GetOutArg(i)); 
      } 
      NLogging.Trace("]"); 
     } 
     if (retMsg.ReturnValue.GetType() != typeof(void)) 
      NLogging.Trace(" returned [" + retMsg.ReturnValue + "]"); 

     NLogging.Trace(")\n"); 
    } 
    #endregion Helpers 
} 

public class TracingProperty : IContextProperty, IContributeObjectSink 
{ 
    #region IContributeObjectSink implementation 
    public IMessageSink GetObjectSink(MarshalByRefObject o, IMessageSink next) 
    { 
     return new TracingAspect(next); 
    } 
    #endregion // IContributeObjectSink implementation 

    #region IContextProperty implementation 
    public string Name 
    { 
     get 
     { 
      return "CallTracingProperty"; 
     } 
    } 
    public void Freeze(Context newContext) 
    { 
    } 
    public bool IsNewContextOK(Context newCtx) 
    { 
     return true; 
    } 
    #endregion //IContextProperty implementation 
} 

[Conditional("DEBUG")] 
[AttributeUsage(AttributeTargets.Class)] 
public class TracingAttribute : ContextAttribute 
{ 
    public TracingAttribute() : base("CallTracing") { } 
    public override void GetPropertiesForNewContext(IConstructionCallMessage ccm) 
    { 
     ccm.ContextProperties.Add(new TracingProperty()); 
    } 
} 

с помощью этого tracingaspect я могу войти информацию о методе only.if я хочу войти метод, из которого был вызван метод .Что я могу сделать?

ответ

2

Установить модификатор доступа класса трассировки публика

public class TracingAspect : IMessageSink 
{ 
    public TracingAspect(IMessageSink next) 
    { 
     m_next = next; 
    } 

Дополнительно:

Внутреннего модификатор доступа модификатор доступа по умолчанию для класса, если он не указан, а внутренний класс доступен только по классам в рамках такой же сборка.

Project1 
    > Class1 
Project2 
    > Class2 (internal) 

Class2 из Project2 доступен только по классам внутри Project2 сборки. Следовательно, Class1 не может создать экземпляр/наследование Class2