gpt4 book ai didi

c# - 如果未缓存在数据库中,则从远程服务获取数据 - 需要建议

转载 作者:太空狗 更新时间:2023-10-29 23:19:27 24 4
gpt4 key购买 nike

在我当前的一个应用程序中,我需要通过 Web 服务/SOAP 从远程服务 (CRM) 获取客户数据。但是我也想把数据缓存在mysql数据库中,这样下次就不用再连接webservice了(数据不常变,远程服务慢而且有带宽限制——所以缓存是可以的/必须的).

我非常确定这项任务的技术部分,但我不太确定如何在我的网络应用程序中实现这种干净和透明。

我的所有其他数据都来自单个 mysql 数据库,因此我的存储库返回列表或使用 NHibernate 从数据库查询的单个实体。

到目前为止我的想法:


1 合一

使用 CustomerRepository,它通过 Id 查找客户,如果成功,则返回它,否则调用 webservice 并将检索到的数据保存到数据库中。

Controller 看起来像这样:

class Controller
{
private CustomerRepository Rep;

public ActionResult SomeAction(int id)
{
return Json(Rep.GetCustomerById(id));
}
}

像这样的伪/简单代码的存储库:

class CustomerRepository 
{
public Customer GetCustomerById(int id)
{
var cached = Database.FindByPK(id);
if(cached != null) return cached;

var webserviceData = Webservice.GetData(id);
var customer = ConvertDataToCustomer(webserviceData);

SaveCustomer(customer);

return customer;
}
}

虽然上面看起来有些简单,但我认为 CustomerRepository 类会变得非常大和丑陋。所以我根本不喜欢这种方法。

存储库应该只从数据库加载数据,至少在我的应用程序中这应该是它的“契约(Contract)”。


2 在 Controller 中分开并粘在一起

为存储库(数据库访问)和网络服务(远程访问)使用单独的类,并让 Controller 完成工作:

Controller 看起来像这样:

class Controller
{
private CustomerRepository Rep;
private Webservice Service;

public ActionResult SomeAction(int id)
{
var customer = Rep.GetCustomerById(id);
if(customer != null) return Json(customer);

var remote = Service.GetCustomerById(id);
Rep.SaveCustomer(remote);

return Json(remote);
}
}

虽然这看起来好一点,但我仍然不喜欢将所有逻辑都放在 Controller 中,因为如果服务不返回数据,错误处理会被省略,并且可能会使事情变得更加困惑。

也许我可以让 Controller 使用另一个服务层,但代码会完全相同,但在另一个类中。

实际上我想让我的 Controller 使用一个封装了这些东西的接口(interface)/类,但我不想要一个“包办一切”的类:访问存储库、访问网络服务、保存数据……我觉得有点不对...



到目前为止,所有想法都/可能会因缓存代码、错误处理等而变得非常臃肿。我认为。

也许我可以使用 AOP 清理一些东西?

将如何实现上述内容?

使用的技术框架:ASP.NET MVC、Spring.NET做DI、NHibernate做ORM、mysql做数据库,通过SOAP访问远程服务。

最佳答案

您可以使用 Decorator 干净地实现您的架构模式。

让我们假设您有一个名为 ICustomerRepository 的接口(interface)。

您首先基于 Web 服务实现 ICustomerRepository(我们称它为 WsCustomerRepository),在此实现中完全不用担心数据库。

然后您实现另一个 ICustomerRepository (MySqlRepository),它与您的数据库对话。

最后,您创建第三个 ICustomerRepository (CachingRepository) 来实现您描述的缓存逻辑。它首先查询“本地”存储库,但如果未从中获得结果,它会查询“远程”存储库并在返回结果之前将结果插入“本地”存储库。

您的 CachingRepository 可能如下所示:

public class CachingRepository : ICustomerRepository
{
private readonly ICustomerRepository remoteRep;
private readonly ICustomerRepository localRep;

public CachingRepository(ICustomerRepository remoteRep, ICustomerRepository localRep)
{
this.remoteRep = remoteRep;
this.localRep = localRep;
}

// implement ICustomerRepository...
}

如您所见,CachingRepository 甚至不必了解具体的 Web 服务和数据库,而是可以专注于其单一职责:缓存

这为您提供了清晰的职责分离,就您的 Controller 而言,它们只与 ICustomerRepository 实例对话。

关于c# - 如果未缓存在数据库中,则从远程服务获取数据 - 需要建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1470291/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com