设计模式跟踪方法 calls/callers

Design pattern tracking method calls/callers

我不知道在特定的软件设计情况下该做什么。刚刚在互联网上搜索解决方案,但没有找到令人满意的答案。所以我只想知道你的专业知识以及最好的做法是什么。 我有一个具有多层抽象的系统。向用户显示的 API 是一个简单的 class,方法数量很少。调用这些方法将在整个抽象过程中触发大量的方法调用。在此过程中将做出某些决定。这条路上的每个元素都可以通过消息系统将决定和决定的原因发送回任何想要阅读它的人。该系统还记录了所有的呼叫和决定,这非常重要 - 甚至是最重要的。老实说这是核心问题。

问题是:我想知道谁调用了某个方法。所以我可以在路上传递某种句柄,每个抽象都知道:"Right, this guy wants that. So i can log: This guy wanted that."

为什么我认为我需要这个是因为不同的其他系统将能够使用它 api。也许一个 GUI 想要放下一个命令,也许是一个 HTTP 驱动的远程控制器,也许是一个硬件触发器,也许是一个自动执行的例程。

我不想让系统根据谁来做决定。我知道这与我抽象所有层的意图完全相反。我只想正确登录。谁想做什么。

现在我只见树木不见森林。我只是向 API 分发了一张类似对象实例的票证。系统正在使用 ID 注册该票证。 API 用户在调用命令时必须交票,以便系统知道是谁调用的。

好吧,把问题写成一句话: 方法的调用者tracking/identifying有好的模式吗?

编辑: 尽管这是一个普遍问题,但在这种情况下使用的语言是 c#!

您可以使用 [CallerMemberName] 属性:

public void SomeMethod(string name, [CallerMemberName] string callerName = null)
{
    Console.Writeline($"SomeMethod was called from {callerName}");
    ...
}

我目前的解决方案非常有效...到目前为止。但是我想知道这是否会被认为是不好的做法,或者您是否会第一眼看到瓶颈。

    //< API user will call this kind of method handing in their requested Accessor!
    public void Command( int a, int b, KomiAccessorBase accessor=null ){
        if( !AccessGranted( accessor ) ) return;
        this.SubController.CommandA( a, b , accessor );
    }

    //< Accessor is checked on validity
    private bool AccessGranted(KomiAccessorBase accessor, [CallerMemberName] string callerName = null ) {
        if (accessor == null) {
            log("KOMI - Access to ["+callerName+"] denied: No Accessor handed in!", MsgType.LOG);
            return false;
        }
        if ( !_kacc_inventory.ContainsKey(accessor.KACCHashId)) {
            log("KOMI - Access to [" + callerName + "] denied: Accessor not registered in KOMI!", MsgType.LOG);
            return false;
        }
        return true;
    }

    protected Dictionary<int, KomiAccessorBase> _kacc_inventory = new Dictionary<int, KomiAccessorBase>();

    //< The Accessor base class. API user have to derive from that!
    public abstract class KomiAccessorBase : RecieverBase, INameable {
        public int KACCHashId { get; private set; }
        private string _name;
        public string Name {
            get {
                return _name;
            }
            private set {

            }
        }
        protected KomiAccessorBase(string name, KOMI komi) : base(komi.Office) {
            Name = name;
            KACCHashId = -1;
            KACCHashId = komi.RegisterAccessor(this); //Perform the real registration
        }
    }

    //< Registeres the Accessor on KOMI for access checking!
    public int RegisterAccessor(KomiAccessorBase acc) {
        if (acc.KACCHashId != -1) return -1; //Abbort registration if already registered!
        int salt = 1;
        int hashId = (salt + "#" + acc.Name).GetHashCode();
        while (_kacc_inventory.ContainsKey(hashId)) {
            salt++;
            hashId = (salt + "#" + acc.Name).GetHashCode();
        }
        _kacc_inventory.Add(hashId, acc);
        return hashId;
    }