我有一个场景,我有一堆工作,我计划在不同的时间运行,工作本身一直在处理,这是伟大的。我有一个抽象的BaseJob类,它们都继承自我用于常见事物的类(如jobPK,startTime,异常日志记录,报告等)。但除此之外,作业是非常不同的,它们具有与它们相关的不同属性和数据,这些特性对于它们来说是特定的(我将这些属性称为JobDetails)。例如:
JobDetails for Job1
-customerId int
-cost double
-sku string
-userDefinedProperties SomeCustomObjectType
JobDetails for Job2
-name string
-executionDate DateTime
-otherProperties SomeOtherCustomObjectType
在基类中,我希望能够以尽可能通用的方式存储对这些JobDetails的引用(换句话说,我不想只将它存储为对象)以最小化拳击的开销/拆箱。然后我想让BaseJob类处理应用程序所需的许多常用功能,例如,如果作业失败,我想将其JobDetails保存到数据库中,以便可以重新启动它,我也想要记录可能发生在给定作业上的任何错误。为此,我需要能够提取那些JobDetails并使用它们。
似乎我需要使用.NET泛型并拥有一类通用属性,我可以填充任何东西,而不必担心打字。处理此问题并使其高效灵活的最佳方法是什么?
我希望这很清楚,谢谢你的帮助
答案 0 :(得分:1)
您可以使JobDetails
实现一个接口,让BaseJob
具有对它的抽象引用。然后在实际的作业中,使用您想要的实现实现抽象JobDetails
。然后让JobDetails
接口定义需要使用的方法BaseJob
。这是Template Method设计模式的略微变化。它看起来像这样:
public interface IJobDetails {
void DoSomeWork();
}
public abstract BaseJob {
protected abstract IJobDetails JobDetails { get; set; }
public ExecuteJob {
//execute the job
JobDetails.DoSomeWork();
}
}
public Job1 : BaseJob {
public Job1() {
JobDetails = new ConcreteJobDetails();
}
protected override IJobDetails JobDetails { get; set; }
}
答案 1 :(得分:0)
怎么样......
public abstract class JobBase<TDetails>
{
private TDetails details;
protected TDetails Details
{
get
{
if (details == null)
{
this.details = this.LoadDetails();
}
return this.details;
}
}
protected virtual TDetails LoadDetails()
{
// Some kind of deserialization of TDetails from your DB storage.
}
}
public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
public class ExampleJobDetails
{
public string ExampleProperty { get; set; }
public int AnotherProperty { get; set; }
}
}
您要么为每个用作TDetails的类型都有表格,要么为所有这些表格提供一个基于键/值的大表格。两者都有利弊。如果你对拳击超级偏执,那么TDetails也不能被限制为一个结构。
编辑:向后看,你想保存失败的详细信息。怎么样......
public abstract class JobBase<TDetails>
{
protected TDetails Details { get; private set; }
public JobBase()
{
this.Details = this.CreateDetails();
}
protected abstract TDetails CreateDetails();
protected void SaveDetails()
{
// Generic save to database.
}
}
public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
public class ExampleJobDetails
{
public string ExampleProperty { get; set; }
public int AnotherProperty { get; set; }
}
protected override ExampleJobDetails CreateDetails()
{
return new ExampleJobDetails() { ExampleProperty = "Hi.", AnotherProperty = 1 };
}
}