我目前正在完成有关对象更改日志功能的工作,并希望对一些内容进行润色。由于我们有很多网页表格/报告应该出现历史数据,我想知道是否有办法在不改变控制/报告的情况下实施。 目前,我有这种情况:
public class Foo {
public string Property1 { get; set; }
public DateTime CreatedDate { get; set;}
public string GetHistoricalValue(string propertyName)
{
HistoryHelper historyHelper = CreateHistoryHelper(this);
return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
}
...
public class HistoryHelper {
public string GetHistoricalValue(string propertyName, DateTime date) {
...
因此,当有人想要获取Property1的历史数据时:
string historicalValue = fooInstance.GetHistoricalValue("Property1");
很明显,这种方法需要对当前应用程序进行大量更改。 当我以常规方式访问Property1时,有没有办法让Foo类返回历史值:
string historicalValue = fooInstance.Property1;
像动态生成具有覆盖属性的子类或其他解决方案的东西? 这可能吗?
答案 0 :(得分:1)
这样的事情:
public class Foo {
public bool HistoricalMode { get; set; }
private string _property1;
public string Property1 {
get {
if (HistoricalMode) {
return GetHistoricalValue("Property1");
} else {
return _property1;
}
set {
if (HistoricalMode){
throw new NotSupportedException("Updates not possible in historical mode.");
} else {
_property1 = value;
}
}
}
public DateTime CreatedDate {
get {
// Similar pattern as above
}
set {
// Similar pattern as above
}
}
public string GetHistoricalValue(string propertyName) {
HistoryHelper historyHelper = CreateHistoryHelper(this);
return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
}
}
基本上,我们的想法是在对象中保留一个布尔值,表示对象处于“历史模式”。如果是这样,请使用您的帮助方法。如果不是,则适用普通属性getter / setter。
我认为这个问题的解决方案需要对框架进行更改(如果您的所有应用程序都有一个框架)。我会按照你加载对象的方式寻求解决方案。希望您可以在“历史模式”和“正常模式”下检测何时需要对象。现在,您只需从数据库中读取对象(记录),在历史模式下,您需要从更改日志功能中组合原始对象(从发生更改时开始)。这样,您当前的所有应用程序都可以(希望)保持原样。您需要做的“唯一”更改是在存储库类中。
这只是推测btw。
答案 1 :(得分:0)
您可以轻松地影响Foo
个实例的创建方式吗?如果是这样,您可以创建派生class HistoricalFoo : Foo
,使Property1
虚拟并使用其getter来更改其行为。然后在需要历史数据时使用HistoricalFoo
。它不是一个非常干净的对象模型,但可以完成工作。
public class Foo
{
protected string _property1;
public virtual string Property1
{
get { return _property1; }
set { _property1 = value; }
}
public DateTime CreatedDate { get; set;}
/* ... */
}
public class HistoricalFoo : Foo
{
public override string Property1
{
get
{
return GetHistoricalValue("Property1");
}
}
}
如果这不适用,可以在Property1
getter中嵌入一些决策逻辑。在这种情况下,您必须更改Foo
实例的内部状态 - 例如,通过设置布尔标志IsInHistoryMode
。但是,更改对象状态可能非常棘手,特别是在多线程环境中。
public class Foo
{
public bool IsInHistoryMode { get; set; }
protected string _property1;
public virtual string Property1
{
get
{
if(IsInHistoryMode)
{
return GetHistoricalValue("Property1");
}
return _property1;
}
set
{
_property1 = value;
}
}
public DateTime CreatedDate { get; set;}
/* ... */
}