ObjectContext 永远不会从接口派生??当ObjectContext有多种类型时,如何应用DI/IoC?

发布于 2024-08-17 11:58:51 字数 198 浏览 7 评论 0原文

如果您的系统具有多种类型的对象上下文。例如:BillingObjectContext、HumanResourceObjectContext 等。所有这些都派生自 ObjectContext,但 ObjectContext 类没有实现像 IObjectContext 那样的任何特定接口。如果使用 Ninject 等多种类型的 ObjectContext,您将如何应用 DI/IoC?

If you have a system that has multiple types of object contexts. For Eg: BillingObjectContext, HumanResourceObjectContext etc. All derive from ObjectContext but ObjectContext Class does not implement any specific interface like IObjectContext. How would you apply DI/IoC in case of multiple types of ObjectContext say using Ninject?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

阳光的暖冬 2024-08-24 11:58:51

如果您必须在测试中依赖它,则必须模拟它。 这是一个示例;它并不比实现接口困难多少。另请参阅 EF 4 中的 TDD 改进

If you must depend on it in a test, you have to mock it. Here's a sample; it's not much harder than implementing an interface. See also TDD improvements in EF 4.

以歌曲疗慰 2024-08-24 11:58:51

为什么我们不能只创建要在测试中使用的实际上下文对象?由于我们不希望测试影响生产数据库,因此我们始终可以指定指向测试数据库的连接字符串。在运行每个测试之前,构建一个新的上下文,添加测试中所需的数据,继续进行单元测试,然后在测试清理部分中删除测试期间创建的所有记录。这里唯一的副作用是自动增量 ID 将在测试数据库中用完,但既然它是一个测试数据库 - 谁在乎呢?

我知道关于这个问题的大多数答案都建议使用 DI/IoC 设计来为数据上下文等创建接口,但我使用实体框架的原因正是为了不为我的数据库连接、对象模型和简单的 CRUD 事务编写任何接口。为我的数据对象编写模拟接口并编写复杂的可查询对象来支持 LINQ,违背了依赖经过高度测试和可靠的实体框架

这种单元测试模式并不新鲜 - Ruby on Rails 已经使用它很长时间了,而且效果很好。正如 .NET 提供 EF 一样,RoR 提供 ActiveRecord 对象,每个单元测试都会创建它需要的对象,继续测试,然后删除所有构造的记录。

如何指定测试环境的连接字符串?由于所有测试都在其自己的专用测试项目中,因此添加一个带有测试数据库连接字符串的新 App.Config 文件就足够了。

想想看,这将为您节省多少头痛和痛苦。

namespace ProjectNamespace
{
    [TestClass]
    public class UnitTest1
    {
        private ObjectContext objContext;

        [TestInitialize]
        public void SetUp()
        {
            // Create the object context and add all the necessary data records.
        }

        [TestMethod]
        public void TestMethod1()
        {
            // Runs the tests. 
        }

        [TestCleanup]
        public void CleanUp()
        {
            // Delete created records. 
        }
    }
}

Why can't we just create the actual context object to be used in our tests? Since we don't want our tests to affect the production database, we can always specify a connection string that points to a test database. Before running each test, construct a new context, add the data you will need in your test, proceed with the unit test, then in the test cleanup section, delete all the records that were created during the test. The only side-affect here would be that the auto-increment IDs would be used up in the test database, but since it's a test database - who cares?

I know that most answers regarding this question propose using DI/IoC designs to create interfaces for data contexts etc. but the reason I am using Entity Framework is exactly to not write any interfaces for my database connections, object models, and simple CRUD transactions. To write mock interfaces for my data objects and to write complex queryable objects to support LINQ, defeats the purpose of relying on highly-tested and reliable Entity Framework.

This pattern for unit testing is not new - Ruby on Rails has been using it for a long time and it's worked out great. Just as .NET provides EF, RoR provides ActiveRecord objects and each unit test creates the objects it needs, proceeds with the tests, and then deletes all the constructed records.

How to specify connection string for test environment? Since all tests are in their own dedicated test project, adding a new App.Config file with a connection string for the test database would suffice.

Just think of how much headache and pain this will save you.

namespace ProjectNamespace
{
    [TestClass]
    public class UnitTest1
    {
        private ObjectContext objContext;

        [TestInitialize]
        public void SetUp()
        {
            // Create the object context and add all the necessary data records.
        }

        [TestMethod]
        public void TestMethod1()
        {
            // Runs the tests. 
        }

        [TestCleanup]
        public void CleanUp()
        {
            // Delete created records. 
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文