【问题标题】:Pattern for Extracting Service Interface from Existing Class Implementation从现有类实现中提取服务接口的模式
【发布时间】:2012-06-27 14:51:32
【问题描述】:

我有一个现有的 Web 应用程序,其中 asp.net 客户端通过使用业务项目的 dll 来使用业务。业务项目的代码如下。

现在,我们需要将其设为 WCF Web 服务。我需要从现有的 BankAccountService 类创建一个服务接口(合同)。但是该类有一个重载的构造函数。此构造函数不能在服务接口中定义(因为 Web 服务不是面向对象的)。我可以在这里使用什么最佳解决方案来使其作为 Web 服务运行?

我们是否需要创建任何外观而不是将 BankAccountService 作为服务实现?

注意:我了解在实现服务后提取接口不是一个好习惯。但是对于这种特殊情况,我们需要这样做。

注意:这是一个非常简单的应用程序,这是应用程序中唯一需要的功能。该网站将是唯一使用该服务的客户。

参考:

1 Interface defining a constructor signature?

代码

namespace ApplicationServiceForBank
{

public class BankAccountService
{

RepositoryLayer.IRepository<RepositoryLayer.BankAccount> accountRepository;
ApplicationServiceForBank.IBankAccountFactory bankFactory;

public BankAccountService(RepositoryLayer.IRepository<RepositoryLayer.BankAccount> repo, IBankAccountFactory bankFact)
{
    accountRepository = repo;
    bankFactory = bankFact;
}

public void FreezeAllAccountsForUser(int userId)
{
    IEnumerable<RepositoryLayer.BankAccount> accountsForUser = accountRepository.FindAll(p => p.BankUser.UserID == userId);
    foreach (RepositoryLayer.BankAccount repositroyAccount in accountsForUser)
    {
        DomainObjectsForBank.IBankAccount acc = null;
        acc = bankFactory.CreateAccount(repositroyAccount);
        if (acc != null)
        {
            acc.BankAccountID = repositroyAccount.BankAccountID;
            acc.accountRepository = this.accountRepository;
            acc.FreezeAccount();
        }
    }
  }
}

【问题讨论】:

  • 这需要一些深入的分析,因为当您从离线 (dll) 迁移到在线 (wcf 服务) 时,您会遇到很多额外的问题。现在是贵公司的会议时间!
  • @Alex 这是一个非常简单的应用程序,这是应用程序中唯一需要的功能。该网站将是唯一使用该服务的客户。您能否列出可能出现的问题?
  • 如果您将现有的服务类抽象为一个业务层/服务层并从 Web/Wcf 服务调用它呢?

标签: c# wcf oop design-patterns soa


【解决方案1】:

如果要将类公开为 WCF 服务,则服务本身需要在构造函数中构建必要的对象,即 RepositoryLayer.IRepository&lt;RepositoryLayer.BankAccount&gt;ApplicationServiceForBank.IBankAccountFactory。这些对象用于检索服务的消费者应该不可知的数据。

在这种情况下,您可以通过 WCF 公开 BankAccountService 并创建各种方法来定义检索数据所需的存储库/工厂类型:

[ServiceContract]
public interface IBankAccountService
{
    [OperationContract]
    void FreezeAllAccountsForUserByAccountTypeFoo(int userId);

    [OperationContract]
    void FreezeAllAccountsForUserByAccountTypeBar(int userId);

    [OperationContract]
    void FreezeAllAccountsForUserByAccountTypeEtc(int userId);
}

由于听起来您正在控制服务的双方,因此另一种选择是将枚举传递给定义所需存储库/工厂类型的方法:

public enum RepoFactory
{
    Foo, Bar, Etc,
}

[ServiceContract]
public interface IBankAccountService
{
    [OperationContract]
    void FreezeAllAccountsForUser(int userId, RepoFactory repoFactory);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2013-01-15
    相关资源
    最近更新 更多