如何使用 PXProtectedAccess 覆盖受保护的方法?
How to override a protected method using PXProtectedAccess?
我需要在生成服务订单时覆盖服务合同计划的下次执行日期。这会根据事件设置自动计算。虽然计算不符合我的要求,所以我需要覆盖它。
查看源代码,我找到了需要重写的方法。不幸的是它被保护了。
我找到了这个 但我没有这么幸运。不确定我在这里错过了什么?我的代码如下:
[PXProtectedAccess]
public abstract class ServiceContractInqExt1 : PXGraphExtension<ServiceContractInq>
{
[PXProtectedAccess]
protected abstract void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow);
}
public class ServiceContractInqExt2: PXGraphExtension<ServiceContractInqExt1,ServiceContractInq>
{
#region Event Handlers
public static bool IsActive()
{
return true;
}
public delegate void UpdateGeneratedScheduleDelegate(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow);
[PXOverride]
public virtual void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow,UpdateGeneratedScheduleDelegate baseMethod)
{
PXTrace.WriteInformation("HIT !");//this is not firing !
baseMethod(scheduleID, toDate, lastGeneratedElementDate, fsScheduleRow);
}
#endregion
}
编辑:
按照下面的答案。
using PX.Data;
using PX.Objects.CR;
using PX.Objects.CS;
using PX.Objects.FS.Scheduler;
using PX.SM;
using System;
using System.Collections;
using System.Collections.Generic;
using PX.Objects.AR;
using PX.Objects;
using PX.Objects.FS;
namespace PX.Objects.FS
{
[PXProtectedAccess]
public abstract class AAServiceContractInqExtension : PXGraphExtension<ServiceContractInq>
{
[PXProtectedAccess]
protected void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow)
{
PXTrace.WriteInformation("HIT");
}
}
}
并且只是加载页面会引发错误。
我的 Acumatica build/version
不幸的是,您将无法覆盖方法 UpdateGeneratedSchedule
,因为它没有标记为 virtual
,因此即使可以访问 ContractGenerationEnqBase
图,我们也无法修改它功能。
考虑到这一点,我成功实施了以下解决方案
public class ServiceContractInqExtension : PXGraphExtension<ServiceContractInq>
{
public delegate void ProcessServiceContractDelegate(PXCache cache, FSContractSchedule fsScheduleRow, DateTime? fromDate, DateTime? toDate);
[PXOverride]
public virtual void processServiceContract(PXCache cache, FSContractSchedule fsScheduleRow, DateTime? fromDate, DateTime? toDate, ProcessServiceContractDelegate del)
{
del?.Invoke(cache, fsScheduleRow, fromDate, toDate);
UpdateGeneratedSchedule(fsScheduleRow.ScheduleID, new DateTime(2023, 3, 11));
}
protected void UpdateGeneratedSchedule(int? scheduleID, DateTime nextExecutionDate)
{
PXUpdate<Set<FSSchedule.nextExecutionDate, Required<FSSchedule.nextExecutionDate>>, FSSchedule,
Where<
FSSchedule.scheduleID, Equal<Required<FSSchedule.scheduleID>>>>
.Update(Base, nextExecutionDate, scheduleID);
}
}
处理方法完成后,自定义 UpdateGeneratedSchedule
将利用 PXUpdate 设置所需的字段值。 PXUpdate 与您最初想要覆盖的方法使用的调用相同。
在这里我们可以看到其中一个处理前的时间表
调用自定义代码后,我们可以看到 'Next Execution Date' 是提供给自定义方法的值。
我需要在生成服务订单时覆盖服务合同计划的下次执行日期。这会根据事件设置自动计算。虽然计算不符合我的要求,所以我需要覆盖它。
查看源代码,我找到了需要重写的方法。不幸的是它被保护了。
我找到了这个
[PXProtectedAccess]
public abstract class ServiceContractInqExt1 : PXGraphExtension<ServiceContractInq>
{
[PXProtectedAccess]
protected abstract void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow);
}
public class ServiceContractInqExt2: PXGraphExtension<ServiceContractInqExt1,ServiceContractInq>
{
#region Event Handlers
public static bool IsActive()
{
return true;
}
public delegate void UpdateGeneratedScheduleDelegate(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow);
[PXOverride]
public virtual void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow,UpdateGeneratedScheduleDelegate baseMethod)
{
PXTrace.WriteInformation("HIT !");//this is not firing !
baseMethod(scheduleID, toDate, lastGeneratedElementDate, fsScheduleRow);
}
#endregion
}
编辑: 按照下面的答案。
using PX.Data;
using PX.Objects.CR;
using PX.Objects.CS;
using PX.Objects.FS.Scheduler;
using PX.SM;
using System;
using System.Collections;
using System.Collections.Generic;
using PX.Objects.AR;
using PX.Objects;
using PX.Objects.FS;
namespace PX.Objects.FS
{
[PXProtectedAccess]
public abstract class AAServiceContractInqExtension : PXGraphExtension<ServiceContractInq>
{
[PXProtectedAccess]
protected void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow)
{
PXTrace.WriteInformation("HIT");
}
}
}
并且只是加载页面会引发错误。
我的 Acumatica build/version
不幸的是,您将无法覆盖方法 UpdateGeneratedSchedule
,因为它没有标记为 virtual
,因此即使可以访问 ContractGenerationEnqBase
图,我们也无法修改它功能。
考虑到这一点,我成功实施了以下解决方案
public class ServiceContractInqExtension : PXGraphExtension<ServiceContractInq>
{
public delegate void ProcessServiceContractDelegate(PXCache cache, FSContractSchedule fsScheduleRow, DateTime? fromDate, DateTime? toDate);
[PXOverride]
public virtual void processServiceContract(PXCache cache, FSContractSchedule fsScheduleRow, DateTime? fromDate, DateTime? toDate, ProcessServiceContractDelegate del)
{
del?.Invoke(cache, fsScheduleRow, fromDate, toDate);
UpdateGeneratedSchedule(fsScheduleRow.ScheduleID, new DateTime(2023, 3, 11));
}
protected void UpdateGeneratedSchedule(int? scheduleID, DateTime nextExecutionDate)
{
PXUpdate<Set<FSSchedule.nextExecutionDate, Required<FSSchedule.nextExecutionDate>>, FSSchedule,
Where<
FSSchedule.scheduleID, Equal<Required<FSSchedule.scheduleID>>>>
.Update(Base, nextExecutionDate, scheduleID);
}
}
处理方法完成后,自定义 UpdateGeneratedSchedule
将利用 PXUpdate 设置所需的字段值。 PXUpdate 与您最初想要覆盖的方法使用的调用相同。
在这里我们可以看到其中一个处理前的时间表
调用自定义代码后,我们可以看到 'Next Execution Date' 是提供给自定义方法的值。