我已经阅读了几十篇关于试图在业务逻辑中模拟\假EF的PRO和CON的帖子.我还没有决定做什么 - 但我知道的一件事是 - 我必须将查询与业务逻辑分开.在这篇文章中我看到拉迪斯拉夫回答说有两种好方法:
- 让它们成为它们的位置,并使用自定义扩展方法,查询视图,映射数据库视图或自定义定义查询来定义可重用部分.
- 将每个查询作为方法公开在某个单独的类上.该方法不得暴露IQueryable,也不得接受Expression作为参数=整个查询逻辑必须包含在方法中.但这将使您的类覆盖相关方法很像存储库(唯一可以被模拟或伪造的).此实现与存储过程使用的实现很接近.
我是否必须封装最简单的查询,例如:
using (MyDbContext entities = new MyDbContext)
{
User user = entities.Users.Find(userId); // ENCAPSULATE THIS ?
// Some BL Code here
}
Run Code Online (Sandbox Code Playgroud)architecture extension-methods unit-testing entity-framework
我正在设计一个我所有客户将连接的2 WCF服务.其中一项服务是通知服务.
我希望每个客户端连接到服务,订阅它,然后使用双工Callback接口接收通知(该服务将触发客户端中的'Notify'操作).
这是我的设计理念:

我的问题是:当每个客户端连接到我的服务时,我将根据我的数据库中的"用户"表进行验证(我将使用UserNamePasswordValidator并实现'验证'功能).
要求:每个用户都需要根据数据库中定义的规则接收不同的通知,但它们都使用相同的合同.
例如:
约翰史密斯在数据库中的规则可能是:通知我所有价格超过100美元的新产品.
Jane Doe在数据库中的规则可能是:在所有名为"JA"的新产品上通知我.
吉姆贾布拉在数据库中的规则可能是:通知我所有"食品"类型的新产品.
我的服务将有一个工作线程,用于检测数据库中的更改(新产品已插入数据库).
然后它应该遍历所有连接的客户端 - 并且每个客户端只有在与客户端的通知请求匹配时才向他发送新产品的通知.
同样 - 所有客户端都会收到相同类型的更新(新产品),但每个客户端应根据数据库中的规则接收不同的产品.
我认为实现这一点的一种方法是使用Singleton服务,该服务包含以下列表:
这样 - 每次工作线程检测到新产品时,它都会遍历此列表并向需要它的人发送通知.这种方法的问题在于,为了拥有一个全球客户列表 - 我需要将服务作为Singlton,对吧?
第二种方法是......好吧......我不知道如何从工作线程访问连接到服务的客户端列表......
我想我遇到的主要问题是每个客户都可能想要通知他不同类型的产品.含义 - pub\sub方法在这里不太好,因为我的场景要求服务了解客户端.
关于如何解决这个令人头疼的问题的任何建议?
我有一个托管在 Windows 服务中的 WCF 服务。
WCF 服务注入了一个ConcurrentQueue<SomeClass>.
Windows 服务(承载 WCF 服务)也注入了ConcurrentQueue<SomeClass>.
Windows 服务启动 WCF 服务,并生成一个工作线程。
工作线程将 ( Enqueue) 对象推SomeClass送到ConccurrentQueue。
我希望以某种方式在对象入ConcurrentQueue队时触发 WCF 服务,以便它可以出队(以及可能在队列中的任何其他对象),并向所有连接的客户端发送消息。
.
两个问题:
如何在注入的 ConccurentQueue 的“入队”方法上使 WCF 服务“挂钩”,以便当对象被推入队列时 - WCF 服务会对此做些什么?
如果我确实设法以某种方式挂钩了“入队”事件,并且现在 Windows 服务中的工作线程已将两个对象排入队列 - 这意味着它还会两次“触发”WCF 服务的“入队挂钩” - 那些两个触发事件发生在不同的线程中?我需要以某种方式确保 WCF 服务按顺序从队列中提取对象。我不想突然看到每个 Enqueue 操作 - WCF 服务在单独的线程中触发并将对象拉出......
我希望我的问题足够清楚......
.
[更新]
在与 Chris 交谈后,我得出的结论是,最好的方法是将工作线程与 WCF 服务分开,并使工作线程作为客户端调用 WCF 服务。这意味着我不必摆弄队列。
关于一件事,我已经读了很多(数十篇文章):
如何对其中包含实体框架代码的业务逻辑代码进行单元测试。
我有3层的WCF服务:
我的业务逻辑将DbContext用于所有数据库操作。现在,我所有的实体都是POCO(以前是ObjectContext,但我对此进行了更改)。
我已阅读拉吉斯拉夫Mrnka的答案在这里,并在这里 的原因,我们应该不假\伪造的DbContext。
他说: “这就是为什么我认为处理上下文/ Linq到实体的代码应该包含集成测试并针对实际数据库进行工作的原因。”
并且: “当然,您的方法在某些情况下有效,但单元测试策略必须在所有情况下均有效-要使其起作用,必须将EF和IQueryable完全从已测试的方法移开。”
我的问题是-您如何实现这一目标???
public class TaskManager
{
public void UpdateTaskStatus(
Guid loggedInUserId,
Guid clientId,
Guid taskId,
Guid chosenOptionId,
Boolean isTaskCompleted,
String notes,
Byte[] rowVersion
)
{
using (TransactionScope ts = new TransactionScope())
{
using (CloseDBEntities entities = new CloseDBEntities())
{
User currentUser = entities.Users.SingleOrDefault(us => us.Id == loggedInUserId);
if (currentUser == null)
throw new Exception("Logged …Run Code Online (Sandbox Code Playgroud) 我有一个WCF服务,所有客户端都连接到该服务,以获取通知\提醒(使用他们实现的CALLBACK接口).目前,WCF服务是自托管的,但计划是将其托管在Windows服务中.
WCF服务具有"发布","订阅"和"取消订阅"操作.
我需要有一个后台工作线程,不断[每隔XXX分钟]轮询一个SQL服务器数据库表,并寻找某些'提醒'行.一旦找到它们 - 它应该通知所有连接的客户端.
我想到了实现这一目标的两种方法.
.
方法A:
有一个单独的EXE项目(不希望它是一个控制台,那应该是什么 - 一个Windows服务?),它将启动并运行一个后台线程.后台线程将作为其客户端之一连接到"Reminder"服务.后台线程将轮询数据库,一旦找到某些内容 - 它将向WCF服务发送'发布'消息,这将使WCF服务向所有订阅的客户端发送提醒.
.
方法B:
以某种方式使后台线程在 WCF服务项目中运行,并且当它在数据库中检测到新的提醒行时,以某种方式使其"发信号通知"具有该信息的WCF服务,然后WCF服务将该信息发送给所有订阅的客户端. .
.
哪种方法更好?还有其他建议吗?