设计模式跟踪方法呼叫/呼叫者

时间:2017-11-17 09:22:19

标签: c# logging architecture method-call

我不知道在特定的软件设计情况下该怎么做。刚搜索了互联网的解决方案,但没有找到令人满意的答案。所以我只想知道你的专业知识以及最好的实践。 我开始有一个带有几层抽象的系统。向用户显示的API是一个简单的类,具有紧凑的方法数。调用这些方法将在整个抽象过程中一直触发大量的方法调用。沿途将会出现一些决定。通过这种方式,每个元素都可以通过消息系统向那里发送断头和原因,并将其发送给想要阅读它的人。该系统还记录了所有的呼叫和拒绝,这非常重要 - 而且最重要的是。说实话,这是核心问题。

问题是:我想知道世界卫生组织称某种方法。因此,我可以提供一些处理方式,每个抽象都知道:"对,这家伙想要那样。所以我可以记录:这家伙想要那个。"

为什么我相信我需要这个,因为不同的其他系统将能够使用该API。也许GUI想要删除命令,可能是HTTP驱动的远程控制器,也许是硬件触发器,也许是自动执行例程。

我不想让系统根据世界卫生组织的要求做出决定。我知道这与我抽象所有thouse图层的意图完全相反。我只是想正确登录。世界卫生组织希望做什么。

现在我只是看不到树木。我只是让API像对象实例一样分发票证。系统正在使用id注册该票证。 API用户在调用命令时必须提交票证,以便系统知道刚刚调用的人。

好吧,把问题写成单句: 是否有良好的模式来跟踪/识别方法的调用者?

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

2 个答案:

答案 0 :(得分:0)

您可以使用[CallerMemberName]属性:

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

答案 1 :(得分:0)

我目前的解决方案就像一个魅力...到目前为止。但我想知道它是否会被认为是不好的做法,或者你是否会在第一眼就看到瓶颈问题。

    //< 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;
    }