我一直在研究更新现有的代码库,以更好地遵循设计模式,原则,处理单元测试,分离问题等。我对实现许多这些概念不熟悉,因此我仍在进行大量研究并试图了解如何它们可以在当前代码库中实现。当前,每个业务实体都有其自己的vb文件。该vb文件中包含该实体的实体,实体集合和实体dalc类。如果要对实体执行数据库操作,可以通过调用Enity.Save,Entity.Delete等来执行。实体类上的这些方法将创建实体dalc对象,然后调用Save,Delete等方法。在实体dalc对象上。然后,dalc将通过处理低级内容的SqlHelper类调用Save,Delete等存储过程。每个实体类都需要将Location对象传递到其构造函数中。该对象用于了解用户登录到哪个数据库以及为该数据库创建适当的连接字符串。所有数据库都具有相同的架构;它们只是具有不同的名称,并且可以存在于不同的SQL实例上。基本上,每个客户端都有自己的数据库,Location对象会建立一个共享数据库,以根据存储在cookie中的客户端名称找出客户端需要连接的SQL实例。我一直在寻找一种更多的Model / Repository / Service方法,但是Location对象让我望而却步,特别是因为它也需要访问数据库以获取创建正确的连接字符串所需的信息。存储库对象需要连接字符串,但是我看到的所有示例都在类中进行了硬编码。我认为存储库对象将需要采用Location对象的接口,但是我不确定MVC项目是直接执行该操作还是将其传递给服务对象,然后他们将处理该对象。在什么时候位置对象被创建,因为它也需要访问数据库以创建连接字符串,如何创建它?我也不清楚MVC项目如何与服务和存储库层交互。似乎所有内容都应通过服务对象运行,但是为了进行测试,您希望它们采用存储库的接口。这样做意味着MVC项目需要传入存储库对象,但是MVC项目似乎不应该知道存储库对象。但是,如果您只是做基本的CRUD,似乎让MVC项目直接在存储库对象上调用这些方法而不是通过服务对象运行它们会更简单。这是我目前正在研究的示例。计划是现在使用ADO.NET和SQL Server,但将来可能会切换到ORM甚至是另一个SQL后端。我希望Model / Repository / Service方法将使将来进行这些更改变得容易,因此,如果不能随意就此提供建议的话。项目模型public class Person{ public int Id; public string Name;}项目存储库public class PersonRepository{ public Person FindById(int id) { // Connect to the database based on the Location's connection string }}项目服务public class PersonService{ private IPersonRepository _personRepository; // Should this even take in the repository object? public PersonService(IPersonRepository personRepository) { _personRepository = personRepository; } // Should the MVC project call this directly on the repository object? public Person FindById(int id) { return _personRepository.FindById(id); }}项目// I think the Location object needs to come from here, as the client name is// in the cookie. I'm not sure how the controllers should interact with the// service and repository classes. 最佳答案 我赞同@Christian的建议。使用ORM将大大简化您与底层数据存储的交互; NHibernate是一个不错的选择。但是,在您的示例中,与表示(又称为ASP.NET MVC项目)中的数据层进行交互的常用方法是将服务注入为控制器的依赖项。有几种方法可以做到这一点,最简单,最直接的方法是use a dependency injection framework (like Unity)实例化您在控制器的构造函数中指定的服务,public class PersonController : Controller{ private readonly IPersonService personService; public PersonController(IPersonService personService) { this.personService = personService; }}另一种方法是implement your own ControllerFactory implementation并根据需要注入所需的服务。还有很多工作要做,但是如果有时间的话,您可以学到有关ASP.NET MVC路由流程的全部流程和DI本身的大量信息。在DI框架中,您(通常)用具体的类实现注册接口,基本上是说,当需要IPersonRepository的实例时,请使用PersonRepositoryImpl的新实例。使用这些注册规则后,DI框架将递归实例化每个依赖项,使其在类构造函数中出现。换句话说,当您请求PersonController的实例时,DI框架将尝试创建类型为PersonController的实例。当看到构造函数需要一个IPersonService类型的参数时,它首先尝试基于相同的规则实例化一个。因此,该过程再次开始,直到所有依赖项都已解决并注入到PersonController的构造函数中为止,resolve PersonController -> construct PersonController(IPersonService personService) -> resolve IPersonService with PersonService -> construct PersonService(IPersonRepository personRepository) -> resolve IPersonRepository with PersonRepository -> construct PersonRepository() <- this one has no dependencies并备份堆栈,直到返回新的PersonController实例。*要使此方法起作用,您必须为给定的类只有一个公共构造函数,其中每个参数都是需要解析的依赖项(您的示例将其固定下来)。如果依赖项的类型未在框架中注册,则解析将失败。如果有多个公共构造函数,则解析也将失败(没有确定方法来确定要使用哪个构造函数),除非您注册应使用哪个构造函数(通常使用属性,但这取决于所使用的DI框架)。某些DI框架(如Unity)可能根本不允许您使用构造函数(默认为空的,无参数的构造函数),并且具有作为依赖属性标记为依赖属性的公共属性。我建议不要使用此方法,因为它无法从使用者类中了解类需要什么依赖项(而无需使用Reflection检查所有属性并查看哪些属性标记为依赖项),这反过来会导致无数的 s。关于c# - 基于数据库值的具有动态连接字符串的存储库模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21365672/
10-10 07:53