从模型内部或外部调用Web服务?

时间:2010-08-04 16:16:51

标签: asp.net-mvc web-services architecture

我正在寻找关于我正在创建的应用程序架构的一些指导。情况如下:

我们公司向销售人员发放奖励卡,然后分发给客户(像借记卡一样使用)。出于跟踪目的,销售人员必须在使用卡之前请求从我们的系统激活(提供有关他们给卡的人以及原因的信息)。面向前端的应用程序是ASP.NET MVC 2.一个Windows服务将定期检查激活请求,并从发行该卡的公司(实际上有两家卡公司和两个服务)调用Web服务来激活它。然后它会在DB中激活卡的状态。

我的解决方案分为5个项目:Web,数据(模型和存储库),CompanyClients(访问两个Web服务),Service(Windows服务)和测试。

目前的情况是,Windows服务中的一些代码可能如下所示:

using (var repo = new Repository())
{
    var cards = repo.GetAllPendingCardsWithOrderAndCompany();

    foreach (var card in cards)
    {
        var client = CompanyClientFactory.GetClient(card);

        try
        {
            client.ActivateCard(card);
            card.ActivationDt = DateTime.Now;
        }
        catch(Exception ex)
        {
            // Error logging goes here
        }
    }
    repo.Save();
}

这有效,但我不禁想到Anemic Domain Model的问题。我应该向Card添加一个名为Activate()的方法,它获取Web服务客户端并尝试真正的激活并自行记录吗?这将使Windows服务更加清洁:

using (var repo = new Repository())
{
    var cards = repo.GetAllPendingCardsWithOrderAndCompany();

    foreach (var card in cards)
    {
        card.Activate();
    }
    repo.Save();
}

但是,这需要Data项目引用CompanyClients。 CompanyClients本身已经引用了Data,因此这将创建循环依赖。我可以将这两个项目混为一谈,但这对我来说并不合适(事实上,我最终会去POCO并将模型和数据访问分割到不同的项目中)。

有关更好地组织此方法的想法吗?

2 个答案:

答案 0 :(得分:1)

最后,从OO角度来看,是否从Card类内部或外部接听电话的答案来自于对它的深入思考。虽然乍看起来将这些功能组合在一起看起来很不错,但是卡片激活它本身是没有意义的。所以在任何情况下,它都属于Card类之外。

关于如何分离各种项目的问题,我认为this answer是有意义的,它使用了一个单独的界面,有一个很棒的教程:Refactoring Service Dependencies to Separated Interface

答案 1 :(得分:0)

是的,我理解你的问题,你问是否可以将数据访问方法放在Model类上,或者将它留在Clients,这是一个包含访问Web服务的方法的项目。

我对类似的项目有类似的想法,我决定让Model类非常简单,它们实际上没有任何方法,只有属性。

此外,客户端与Web服务建立连接的概念也感觉不对。客户也应该进入模型项目。您现在用于连接到webservices的代码应该移动到一个名为WebServiceProxy的单独项目或类似的东西。

此项目应遵循Repository/Service pattern。链接的文章实际上讨论了与webservices相关的存储库模式(除了通常的Repository到DB之外的东西)。

HTH