我正在使用Entity Framework开展我的第二个项目,我想阅读一些关于代码是否符合其良好编码实践的意见。
我建议的架构是这样的:
因此,网站调用业务逻辑,业务规则在那里进行评估。 它调用DALFacade,它只是对于上层是不可见的,无论我们是否访问db2或sql server。
EF DAL,它负责与数据库交谈,CODE FIRST Approach。 实体类库是带有poco类的项目。 实用程序是不言自明的,我可能会把代码写成从活动目录中读取属性。
这是我的代码,我尽可能简化它
OnePage:
protected void BtnSubmitRequestClick(object sender, EventArgs e)
{
var ecoBonusWorkflow = new EcoBonusWorkflow
{
IsOnHold = true
};
BusinessLogic.EcoBonusRequestSave(ecoBonusWorkflow);
}
BUsiness Logic:
public static class BusinessLogic
{
public static void EcoBonusRequestSave(EcoBonusWorkflow ecoBonusWorkflow)
{
if (true)
{
DalFacade.EcoBonusRequestSave(ecoBonusWorkflow);
}
}
}
DALFacade:
public static class DalFacade
{
private static readonly UnitOfWork UnitOfWork = new UnitOfWork();
public static void EcoBonusRequestSave(EcoBonusWorkflow ecoBonusWorkFlow)
{
UnitOfWork.EcoBonusWorkflowRepository.InsertEcoBonusWorkflow(ecoBonusWorkFlow);
}
}
然后在EF Dal类库中,我使用传统的EF 4.1 Code First Approach。 我还使用了存储库模式和工作单元。
欢迎任何观察
答案 0 :(得分:2)
包含'实用程序'对我来说似乎很奇怪。其他所有东西都有一个很好的命名,它具有非常具体的设置,它应该做什么,然后你有一个模糊命名的'实用程序'块。
这不是任何特定的编码标准,但我会尽可能避免将“实用程序”整合到您的顶级架构中。每个项目都有一些名为“helpers”或“utilities”的文件夹,它最终成为大量杂项代码的转储,似乎不会立即适合其他任何地方。这正是技术债务和意大利面条代码开始的方式。
除非你是该项目的唯一开发者,否则无论你出现什么,它都可能最终会发生,但不过我会避免让它合法化。
另外,在你的快速和肮脏警报中包含静态类我。除了静态代码损害可测试性这一事实外,实体框架不是线程安全的。你可以通过线程安全的方式使用它,所以如果你有任何多线程或协同处理,你的DALFacade会随机抛出大量错误并成为一个巨大的头痛。
我也没有在设计中看到任何依赖注入的限制,这再次涉及代码的可测试性。
编辑:好的,这些不是Stack的让步,所以是时候介绍dependency injection的想法。
基本上,任何时候你做某事都直接取决于其他东西,例如当你调用一个静态类时,你将这两个东西捆绑在一起。如果不修改或更换其他部件,则一部分不再可更换。这是一个坏事,因为它使重构和更改一个非常大的问题。您想要做的是“松散地”耦合这些依赖关系,这样您就可以在不破坏所有内容的情况下更改部件。在C#/ .NET中,您通常使用接口来执行此操作。
因此,不要使用“DALFacade”直接传递它,而是要有一些效果:
interface IDalFacade
{
int DoAThing();
bool DoAnotherThing();
}
class DalFacade : IDalFacade
{
public int DoAThing()
{
return 0;
}
public bool DoAnotherThing()
{
return false;
}
}
然后您可以在业务逻辑中使用它,如下所示:
class BusinessLogic : IBusinessLogic
{
public IDalFacade DalFacade { get; private set; }
public BusinessLogic() : this(new DalFacade())
{}
public BusinessLogic(IDalFacade dalFacade)
{
this.DalFacade = dalFacade;
}
public void LogicTheThings()
{
this.DalFacade.DoAThing();
}
}
现在不再重要的是DalFacade是否完全被破坏,或者突然之间你需要两个不同的东西。甚至,真的,如果一个DalFacade甚至被传入。只要它履行了IDalFacade合同,它就完全没问题了。您仍然可以在没有参数的情况下调用它(它只是假定一个特定的实现),但即使这样也不理想。理想情况下,您可能希望使用依赖注入库,例如Ninject或StructureMap,这样您就可以更轻松地进行任何特定更改。
这在尝试对代码进行单元测试时也很有用,因为正如我所说,你甚至不需要实际的DalFacade来做事情。您可以简单地模拟填充IDalFacade合同的内容(使用RhinoMocks之类的内容),然后您可以将所有代码与项目中的任何其他代码完全分开。