C# 中的面向方面编程

本文关键字:方面 编程 | 更新日期: 2023-09-27 17:56:36

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

使用此跟踪方面,我只能记录有关方法的信息。如果我想记录调用方法的方法。我能做什么?

C# 中的面向方面编程

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

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

附加:

内部访问修饰符

是类的默认访问修饰符,如果未指定任何内容,并且内部类只能由同一程序集中的类访问

Project1
    > Class1
Project2
    > Class2 (internal)

Class2Project2 只能由程序集内部Project2类访问。因此,Class1无法创建实例/继承Class2