c#中面向方面编程

时间:2016-07-13 05:25:34

标签: c# aop

我在SampleClassLibrary中有一个名为DataLayerClass的类。该类具有用于跟踪目的的属性。

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

使用AOP实现此属性。代码如下:

 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());
    }
}

使用此跟踪方法我只能记录有关方法的信息。如果我想记录调用方法的方法。我该怎么办?

1 个答案:

答案 0 :(得分:2)

将跟踪类访问修饰符设置为public

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

其他:

如果没有指定类,则内部访问修饰符是类的默认访问修饰符,并且内部类只能由同一程序集中的类访问。

Project1
    > Class1
Project2
    > Class2 (internal)
Class2的{​​{1}}只能由Project2程序集内的类访问。因此,Project2无法创建实例/继承Class1