| 
			
			 | 
		#1 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
			
			
			call stack parsing as condition for logic
			 
			
			столкнулся тут с необходимостью переписывать кучу стандартных классов, которые через private методы вызывают один public табличный метод, который я легко могу перекрыть. но! в этом методе отсутствует нужный мне аргумент, чтобы определять контекст. и пришла мне в голову шальная мысль, а что если анализировать call stack внутри этого табличного метода, вместо переписывания кучи классов? 
		
		
		
		
		
		
			X++: ...
        container myCallStack;
        int i;
        str whatToWrite;
        myCallStack = xSession::xppCallStack();
        for( i=1; i<=conlen(myCallStack); i++)
        {
            whatToWrite += conpeek(myCallStack, i);
        }
        if(callStackContainWhatINeed(whatToWrite))
        {
            doMyWhim();
        }
...с новым годом, кстати, всех, кто уже очнулся! 
				__________________ 
		
		
		
		
	Felix nihil admirari  | 
| 
	
 | 
| 
			
			 | 
		#2 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Не делал. По виду идеи какой то изврат и не очень понятно зачем так. 
		
		
		
		
		
		
		
	XppCallStack по виду в IL разве будет корректно работать? С наступившим. Всех благ и здоровья вам +близким!  | 
| 
	
 | 
| 
			
			 | 
		#3 | 
| 
			
			 Участник 
		
			
	 | 
	
	|
| 
	
 | 
|
| За это сообщение автора поблагодарили: gl00mie (5). | |
| 
			
			 | 
		#4 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			нет, это не совсем то. моя проблема не в том, что я не могу перекрыть конечный метод - он как раз открыт всем ветрам, а в том, что не могу влезть во все вызывающие его private методы. 
		
		
		
		
		
		
			но считай, что "иронию судьбы" ты всё-таки посмотрел, потому что я опирался на твой собственный пример из этого топика X++: boolean isApplicableTo(AnyType _value) { #localMacro.runningUnitTestsClient '(C)\\Classes\\SysTestSuite\\run' #endmacro #localMacro.runningUnitTestsServer '(s)\\Classes\\SysTestSuite\\run' #endmacro container callStack; if (_value && typeOf(_value) == Types::Class) { callStack = xSession::xppCallStack(); if (conFind(callStack, #runningUnitTestsClient) || conFind(callStack, #runningUnitTestsServer)) { return AOTResourceTemplateProviderTestHelper_RU::applicable(); } } return false; } 
				__________________ 
		
		
		
		
	Felix nihil admirari  | 
| 
	
 | 
| 
			
			 | 
		#5 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			поясни, плиз, что там может некорректно работать?
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	Felix nihil admirari  | 
| 
	
 | 
| 
			
			 | 
		#6 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Была старая дискуссия на яммере о использовании CallContext и все были посланы использовать disposable context из блога выше. Мы его (disposable) частенько используем, работает как часы.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: Logger (3). | |
| 
			
			 | 
		#7 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Так его же надо инициализировать как раз там, где у меня полный приват. То есть это не решение проблемы.  
		
		
		
		
		
		
			Мне не нужен дополнительный аргумент - мне как раз нужно его заполнять 
				__________________ 
		
		
		
		
	Felix nihil admirari  | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		
		
		
		
			 
				__________________ 
		
		
		
		
	Felix nihil admirari  | 
| 
	
 | 
| 
			
			 | 
		#9 | 
| 
			
			 Microsoft Dynamics 
		
			
	 | 
	
	
	
		
		
		
		 
			
			+1 за disposable из блога. Тоже использую по мере надобности не только в кустомерских модификациях, но и для кода написанного для МСа. Code review этот подход проходит.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#10 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			интересно, и что будет, если таких контекстов будет определено несколько, например, через те же расширения в методе insert? throw error('nesting is not supported')?
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	Felix nihil admirari  | 
| 
	
 | 
| 
			
			 | 
		#11 | 
| 
			
			 Microsoft Dynamics 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
  позволяет иметь вложенные контексты. И тут уже в вашей воле реализовать необходимый функционал, типа, какой приоритет имеют поля в вашем контексте.
		 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: wojzeh (5). | |
| 
			
			 | 
		#12 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Парзинг стека приводит к тому, что вызываемый код начинает зависеть от вызывающего  - если нужно будет второе место, из которого надо, определить то же поведение, придется в вызываемую функцию добавлять дополнительную логику.  
		
		
		
		
		
		
		
		
			И disposable context и парзинг стека не позволяет распознать ситуацию, когда чужой код вдруг стал вызывать ту же функцию на каком-то промежуточном уровне еще раз ожидая прежнего поведения. Еще не знаю как Dyn365FO, а в Ax2012, ЕМНИП, xppCallstack не работал из IL - и там пришлось бы пользоваться System.Environmen::get_Stacktrace() Последний раз редактировалось belugin; 07.01.2020 в 15:56.  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: trud (3). | |
| 
			
			 | 
		#13 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			как раз тот случай у меня, когда мне всё равно на другие случаи вызова моего кода, увы, праздник продолжался недолго. 
		
		
		
			столкнулся с другой проблемой: в стеке я вижу абстрактный класс, а не конкретный экземпляр дочернего класса... 
				__________________ 
		
		
		
		
	Felix nihil admirari  | 
| 
	
 | 
| 
			
			 | 
		#14 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Обычно в таких случаях пишется "обертка" для стандартного класса, которая где-то выше по стеку вызовов инициализирует disposable context, а ниже по стеку отрабатывают стандартные private или какие угодно методы, вызывающие нужный код, и этот нужный код "видит", что его вызывают в определенном контексте, если так можно выразиться. Мне кажется, стоит все же посмотреть в сторону disposable context, а анализ стека вызовов, по-моему, - тупиковая ветвь развития, так вы заставите свой вызываемый код, как уже отмечалось, слишком много знать про вызывающий. Потом добавят какие-нить lambda-функции, которые в стеке вызовов будут выглядеть иначе, - и всё у вас сломается.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: trud (1), wojzeh (3). | |
| 
			
			 | 
		#15 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Кстати про парсинг стека: кто-нибудь в курсе, нужно ли использовать Code Access Permission, или в D365FO все эти "new ExecutePermission().assert()" стали чем-то вроде рудиментов тазовых костей у китов? Если не ошибаюсь, эта фича использовала стек?
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#16 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Не нужно
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: Stitch_MS (3). | |
| 
	
	 | 
	
		
  |