【问题标题】:Use of context and repository in EF WCF services在 EF WCF 服务中使用上下文和存储库
【发布时间】:2014-01-21 10:24:41
【问题描述】:

我首先使用存储库模式在我的数据层中使用实体框架代码。我目前正在设计我的 WCF Web 服务以连接到数据层,我只是对如何连接到数据层有点困惑。

在我的数据层测试项目中,我为每个测试创建一个新的 DbContext 类,将其包装在 using 块中,在其中创建存储库类,将上下文作为构造函数参数传递。然后我可以在存储库上调用我的方法来取回数据。

这对于开始是否正确,然后我是否在 WCF 服务方法中也这样做?

我会不会有

 public class UserService : IUserService
    {
        public bool CheckEmailAvailability(string email)
        {
            try
            {
                using (var context = new MyDbContext())
                {
                    var repository = new UserDataRepository(context);
                    var emailAvailable =
                        repository.GetItems().Count(
                            u => u.EmailAddress.Equals(email, StringComparison.InvariantCultureIgnoreCase)) == 0;

                    return emailAvailable;
                }
            }
        }
    }

还是我使用的上下文/存储库概念错了?

我还觉得在这里使用 DI 会很方便,这样我就可以在 WCF 服务测试项目中模拟数据上下文/存储库对象。这是通常做的事情吗?如果是这样,有没有人有任何关于这方面的示例或教程的链接?

【问题讨论】:

    标签: c# wcf entity-framework testing mocking


    【解决方案1】:

    首先,是的,最好注入存储库,或者(如果您选择的 DI 框架无法解析它们)存储库的工厂。

    此外,从您的服务中删除上下文的想法可能是一个好主意。在我看来,存储库及其助手应该处理上下文,并在必要时在组装实体所需的各种数据库调用之间共享上下文。然后服务可以从存储库中请求实体,而不必担心它们是来自数据库还是其他数据存储。

    public class UserService: IUserService
    {
        IUserRepository userRepository;
    
        ... // ctor to inject repository
    
        public bool CheckEmailAvailability(string email)
        {
            var emailAvailable = !userRepository.GetUserEmails().Any(u => u.EmailAddress.Equals(email, StringComparison.InvariantCultureIgnoreCase));
    
            return emailAvailable;                            
        }
    }
    
    public class UserRepository: IUserRepository
    {
        ...
    
        public IEnumerable GetUserEmails()
        {
            // actually this context should be handled more centrally, included here for sake of illustration
            using (var context = new MyDbContext()) 
            {
                return repository.GetItems();
            }
        }
    }
    

    最后,关于 WCF 服务,我不确定最好的建议是什么。我见过在业务逻辑中间创建 WCF 服务的代码,这很糟糕,但是旧 WPF 代码库和有限 DI 的限制。更好的情况是可以将 ChannelFactory 或服务工厂注入到您的服务层中。您可能会在 Dependency Injection wcf 上找到此答案有帮助。

    和往常一样,如果您打算对代码进行 TDD,我绝对建议您将应用程序各层之间的交点封装在接口中,以便更容易模拟它们。听起来您的想法是对的。

    【讨论】:

    • 我一直在争论用哪种方式来获得上下文和存储库,并同意让代码处理存储库似乎更有意义。问题是您是否必须对结果进行查询,例如,您在存储库中有一个名为 GetItems() 的方法。在此,您在 using 块中创建上下文,从 EF 中选择并将结果作为 Queryable() 返回。然后您不能在调用方法中查询项目,因为上下文已被释放
    • 啊,我明白了。我必须承认,我已经忘记了与 EF 的那个特殊问题。在我的上一个项目中,使用 EF 进行的不仅仅是数据库定义,初始选择将从存储库中的 EF 进行(例如,通过电子邮件地址选择或全选)并作为集合解析,然后业务逻辑将使用 linq 来执行它想要返回的集合的任何其他内容。根据我的经验,很多时候 EF 带来的麻烦多于其价值,而 SimpleData 之类的替代方案更易于使用。我希望这会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多