我考虑使用以下abstract class
作为数据库迁移的基础:
using System.Threading.Tasks;
public abstract class MigrationBase
{
public abstract string Name { get; }
public abstract string Description { get; }
public abstract int FromVersion { get; }
public abstract int ToVersion { get; }
public abstract void Apply();
public abstract Task ApplyAsync();
}
现在,根据底层数据库系统,将编写具体的迁移,实现void Apply
或Task ApplyAsync
方法可能更有意义。我看到以下选项:
MigrationBase
,SyncMigrationBase
和AsyncMigrationBase
以及在任何地方使用类型转换对我来说似乎都不合理。现在你可能会说我可以选择第二选项,因为ADO.Net提供同步和异步方法,而在大多数情况下数据库适配器将提供两种变体。如果你在没有考虑ADO.Net的情况下查看更普遍的问题,是否有更好的解决方案?
如果我选择了第二选项,我是否应该提供一个预先实现的Task ApplyAsync
版本,类似于微软对System.IO.Stream.ReadAsync
所做的那样,同时考虑了Stephen Toub编写的内容?如果是的话,我还应该注意什么?
答案 0 :(得分:6)
单独使用ApplyAsync
,然后删除其他方法。
如果我决定使用两种抽象方法中的一种,我强迫开发人员实现具体的迁移,以一种方式或另一种方式做错了
如果用户需要从接口或抽象类实现async
方法,但他必须同步完成所有操作,那么用async
方法替换Task
绝对没有问题使用同步方法,它返回从result构造的已完成任务。
另一方面,您的代码始终执行调用,就好像它们是异步的一样。
如果我决定使用这两种抽象方法,那么只要数据库系统不提供这两种可能性,我就强迫他做错了。
没错,暴露两种方法都是一种更糟糕的选择。
拥有
MigrationBase
,SyncMigrationBase
和AsyncMigrationBase
以及在任何地方使用类型转换对我来说似乎都不合理。
我认为你是对的,为可以“折叠”到基类中的内容添加一个子类确实看起来比必要的更多努力。