我最近进入了C#的高级阶段,并且我看到很多应用程序实现了丢失耦合和依赖注入。我已经看过"服务"与课程相关的很多,我想你会称它们为服务类?我还看到这个项目中的课程包括Repository这个词,比如说你有一个名为“玩家”的人,还有2个以上的课程和玩家服务'和' PlayerRepository'类。
我检查了Linda,TreeHouse,Udemy和许多其他网站。我甚至谷歌这个主题,但它似乎带来了数百个结果所有导致不同的事情。这些链接中没有一个真正以简单明了的细节回答我的问题,至少我无法理解。
任何人都可以帮忙解释一下吗?为什么我需要它们,何时使用它们,它们是什么?
答案 0 :(得分:0)
嗯,很难在没有看到代码的情况下做出具体的解释,但总的来说,Repository的概念是指数据层组件和术语服务 - 主要是在ASP.NET世界中指的是业务层组件。
您可以将这些图层彼此分开,以便可以单独维护,测试和扩展它们。理想的体系结构通过接口公开这些层的功能 - 尤其是存储库层。在Service层上,您可以通过构造函数将这些依赖项作为Interfaces。使用IoC容器和依赖注入模式,您可以将具体类注册到这些接口,并在中心位置构建对象。对象组合根。这允许您在中心位置轻松管理依赖项,而不是实例化每个依赖项,在代码中分散的位置传递。
这个答案只是一个给你概述的指针。这些是您应该通过自我研究和消化深入研究的主题。
答案 1 :(得分:0)
Repository模式用于抽象出类的持久化方式。这允许您更改基础数据库或ORM映射器,而不会影响持久化类。请参阅Using Repository Pattern for Abstracting Data Access from a Cache and Data Store。
如果多个类参与某个用例,则使用服务,并且这些类中没有一个应该负责协调其他类。 (也许这些类甚至不能直接引用彼此。)在这种情况下,将处理类之间相互作用的代码放入服务方法中,并将受影响的对象传递给它。
请注意,如果受影响的类处于直接的父子关系中,您可以让父级直接协调其子级,而不引入服务。但这可能导致代码难以理解。
让我举个例子:假设我们想提交交易。提交事务后,我们希望使用最近事务的(非规范化)时间戳更新具有事务的Person。如您所见,Person
没有直接引用该事务。
public class Person {
public long Id { get; set; }
public string Name { get; set; }
public DateTime? LastTransactionTimestamp { get; set; }
}
public class Transaction {
public long Id { get; set; }
public long PersonId { get; set; }
public DateTime Timestamp { get; set; }
public void Commit() {
Timestamp = DateTime.Now;
}
}
现在我们遇到了应该把逻辑放在哪里的问题。如果我们将它放入Person
类,则需要Repository访问权来加载Transaction(因为它没有直接引用)。但它应该只关注存储自己的数据,而不是从数据库加载不相关的数据。如果我们将它放入Transaction
类,它不知道它是否是此Person的最新Transaction(因为它没有看到其他事务)。
所以解决方案是将逻辑放入服务中。如果服务需要数据库访问,我们会在其中注入一个存储库。
public class PersonTransactionService {
private readonly IDbSet<Transaction> _allTransactions;
public PersonTransactionService(IDbSet<Transaction> allTransactions) {
_allTransactions = allTransactions;
}
public void Commit(Person person, Transaction transaction) {
transaction.Commit();
var mostRecent = _allTransactions
.Where(t => t.PersonId == person.Id)
.OrderBy(t => t.Timestamp)
.LastOrDefault();
if (mostRecent != null) {
person.LastTransactionTimestamp = mostRecent.Timestamp;
}
}
}