依赖注入和工厂

时间:2010-06-10 12:15:33

标签: c# dependency-injection factory-pattern

试图找出如何最好地处理以下情况:

假设一个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

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

我缺少更好/更可发现的方式吗?

2 个答案:

答案 0 :(得分:5)

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

从IRequestContext的消费者的角度来看,RequestContext及其依赖关系的存在纯粹是实现细节。由于Liskov Substitution Principle,消费者必须只处理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...
}

只有在应用程序的Composition Root,您才需要最终将所有内容连接在一起。这是一个穷人的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);

答案 1 :(得分:0)

工厂模式是一种众所周知,记录和使用的方法。 如果您担心其他开发人员没有达到速度,那么请在代码中的(xml)文档中添加wikipedia's factory pattern page的链接。

此外,请确保您明确地命名您的工厂 - Microsoft似乎喜欢提供商后缀。