良好的编码实践

时间:2012-05-07 15:51:26

标签: c# entity-framework entity-framework-4

我正在使用Entity Framework开展我的第二个项目,我想阅读一些关于代码是否符合其良好编码实践的意见。

我建议的架构是这样的:

enter image description here

因此,网站调用业务逻辑,业务规则在那里进行评估。 它调用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。 我还使用了存储库模式和工作单元。

欢迎任何观察

1 个答案:

答案 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合同,它就完全没问题了。您仍然可以在没有参数的情况下调用它(它只是假定一个特定的实现),但即使这样也不理想。理想情况下,您可能希望使用依赖注入库,例如NinjectStructureMap,这样您就可以更轻松地进行任何特定更改。

这在尝试对代码进行单元测试时也很有用,因为正如我所说,你甚至不需要实际的DalFacade来做事情。您可以简单地模拟填充IDalFacade合同的内容(使用RhinoMocks之类的内容),然后您可以将所有代码与项目中的任何其他代码完全分开。