6

试图弄清楚如何最好地处理以下情况:

假设一个RequestContext类依赖于外部服务,例如:

public class RequestContext : IRequestContext
{
    private readonly ServiceFactory<IWeatherService> _weatherService;

    public RequestContext(ServiceFactory<IWeatherService> weatherService, UserLocation location, string query)
    {
       _weatherService = weatherService;
       ...

我应该在最终实例化的类中要求什么样的依赖RequestContext?可能是ServiceFactory<IWeatherService>,但这似乎不对,或者我可以按照IRequestContextFactory以下方式为它创建一个:

public class RequestContextFactory : IRequestContextFactory
{
    private readonly ServiceFactory<IWeatherService> _weatherService;

    public RequestContextFactory(ServiceFactory<IWeatherService> weatherService)
    {
        _weatherService = weatherService;
    }

    public RequestContext Create(UserLocation location, string query)
    {
        return new RequestContext(_weatherService, location, query);
    }
}

然后IRequestContextFactory通过构造函数注入。

这似乎是一个很好的方法,但这种方法的问题是我认为它阻碍了可发现性(开发人员必须了解工厂并实施它,这并不是很明显)。

我错过了更好/更容易发现的方式吗?

4

2 回答 2

5

松耦合的美妙之处在于我们可以不断地隐藏之前的细节

从 IRequestContext 消费者的角度来看,RequestContext 及其依赖项的存在纯粹是一个实现细节。由于Liskov 替换原则,消费者必须只处理 IRequestContext:

public class MyClass
{
    private readonly IRequestContext reqCtx;

    public MyClass(IRequestContext reqCtx)
    {
        if (reqCtx == null)
        {
            throw new ArgumentNullException("reqCtx");
        }

        this.reqCtx = reqCtx;
    }

    // Implement using this.reqCtx...
}

只有在应用程序的组合根中,您才需要最终将所有内容连接在一起。这是一个穷人的 DI 方法的草图:

ServiceFactory<IWeatherService> weatherService =
    new ServiceFactory<IWeatherService>();
UserLocation location = new UserLocation;
string query = "foo";

IRequestContext reqCtx = new RequestContext(weatherService, location, query);

var mc = new MyClass(reqCtx);
于 2010-06-10T12:28:03.847 回答
0

工厂模式是一种众所周知的、文档化的和使用过的方法。如果您担心其他开发人员无法跟上速度,那么在代码中的 (xml) 文档中放置一个指向wikipedia 工厂模式页面的链接。

另外,请确保您一致地命名您的工厂 - 微软似乎喜欢 Provider 后缀。

于 2010-06-10T13:10:07.540 回答