4

我正在开发一个 WCF Web 服务,它从基于string providerCode.

在最高级别,服务调用一个StaticBroker类,该类检查providerCode并返回 的适当子类DataManager,比方说MyDataManager。然后服务调用MyDataManager.getVehicleFetcherForStop()返回一个类的实例,该实例VehicleInfoFetcher用于获取信息。

我对这一切都很陌生,我想我可能设计错了。这是我现在如何做的代码(简化):

服务.svc.cs

// Public-facing web service method
public string getRealtimeInfo(String stopID, string providerCode = "UK")
{
    DataManager dm = StaticBroker.Instance.dataManager(stopID);
    return dm.getUpcomingVehicleInfoNow(primaryCode);
}

静态经纪人

public sealed class StaticBroker
{    
  UKDataManager ukDataManager = null;

  // Create one instance of each data manager when the Web Service is started,
  // to save memory
  private StaticBroker()
  {
      ukDataManager = new UKDataManager();
  }

  public DataManager dataManager(string providerCode)
  {
     if (providerCode.Equals(UKDataManager.DEFAULT_PROVIDER_CODE))
        return ukDataManager;
     // else if...
  }

  // Most singleton stuff snipped out
  private static readonly StaticBroker instance = new StaticBroker();
}

UKDataManager

public class UKDataManager : DataManager
{
    public const string DEFAULT_PROVIDER_CODE = "UK";

    public string getUpcomingVehicleInfoNow(string stopID)
    {
        VehicleInfoFetcher infoFetcher;
        if ( shouldCheckDB(stopID))
            VehicleInfoFetcher infoFetcher = new DatabaseVehicleInfoFetcher("UK");
        else 
            fetcher = new UKLiveVehicleInfoFetcher();

            return fetcher.getVehicleInfo(primaryCode).Result;  // This is an async method, but we wait for the result
        }
    }
}

如您所见,我有一个 Singleton StaticBroker,它本身只存储每种类型的DataManager. 最后,在 DataManagers 中,创建了执行实际工作的类的实际实例,SomeVehicleFetcher.

这是一种明智的做法吗?或者当 Web 服务的并发使用率很高时,这些单例和共享实例会导致问题吗?我担心创建大量新实例可能会导致内存问题。如您所见,我并不真正了解应用程序的生命周期/内存周期在 Web 服务中是如何工作的。

4

1 回答 1

3

您正在尝试使用您认为不正确或不需要的设计来解决假设问题(“可能导致内存问题”)。此外,ADO.NET 有大量优化处理数据库连接性能。

这只会带来更多的工作和更多的测试难题(您将如何隔离依赖于该代理的代码?)。

请参阅反模式:

过早的优化,不是在这里发明的

编辑:

public interface IVehicleInfoRetriever {
    VehicleInfoResponse getVehicleInfo(string primaryCode);
}

public class DataManager<TVehicleInfoFetcher> 
    where TVehicleInfoFetcher : class, new(), IVehicleInfoRetriever 
{

    private string _providerCode;

    public DataManager() : this("UK") { }

    public DataManager(string providerCode) {
        _providerCode = providerCode;
    }

    public string getUpcomingVehicleInfoNow(string stopID)
    {
        VehicleInfoFetcher infoFetcher;
        if ( shouldCheckDB(stopID))
            VehicleInfoFetcher infoFetcher = new DatabaseVehicleInfoFetcher(_providerCode);
        else 
            fetcher = new TVehicleInfoFetcher();

            return fetcher.getVehicleInfo(primaryCode).Result;  // This is an async method, but we wait for the result
        }
    }

}

这样的事情消除了对“经纪人”的需求。

此外,您称为“代理”的类更像是工厂,工厂已经失宠,因为它们允许在杂草中而不是在顶部指定依赖注入,并且它们为单元测试进行环境配置复杂的事业。

当然,DataManager 的风格之间可能有比您所展示的更多的不同。如果是这种情况并且它们不能集中化,那么我建议您调查许多可用的控制反转容器之一(想到 AutoFac、Unity、Castle Windsor)。这些容器将根据最顶部的提供程序代码的运行时值保留使用哪种风格的 DataManager 的逻辑。

于 2013-08-01T14:35:28.737 回答