依赖注入和工厂

发布于 2024-09-05 06:40:18 字数 1209 浏览 3 评论 0原文

尝试找出如何最好地处理以下场景:

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

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

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

我应该在最终实例化的类中需要什么样的依赖关系 <代码>RequestContext?它可能是 ServiceFactory,但这似乎不对,或者我可以按照以下方式为其创建一个 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 通过构造函数注入。

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

我是否缺少更好/更容易发现的方式?

Trying to figure out how to best handle the following scenario:

Assume a RequestContext class which has a dependency to an external service, such as:

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

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

What sort of dependency should I require in the class that will ultimately instantiate RequestContext? It could be ServiceFactory<IWeatherService>, but that doesn't seem right, or I could create an IRequestContextFactory for it along the lines of:

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);
    }
}

And then pass the IRequestContextFactory through constructor injection.

This seems like a good way to do it, but the problem with this approach is that I think it hinders discoverability (devs must know about the factory and implement it, which is not really apparent).

Is there a better/more discoverable way that I'm missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绅士风度i 2024-09-12 06:40:18

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

从 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...
}

仅在应用程序的 < a href="https://stackoverflow.com/questions/1475575/where-should-i-do-dependency-injection-with-ninject-2/1475861#1475861">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);

The beauty of loose coupling is that we can constantly hide away the previous details.

From the perspective of a consumer of IRequestContext the existence of RequestContext and its dependencies is purely an implementation detail. Because of the Liskov Substitution Principle, the consumer must only deal with 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...
}

Only at the application's Composition Root do you need to finally wire everything together. Here's a sketch of a Poor Man's DI approach:

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);
风追烟花雨 2024-09-12 06:40:18

工厂模式是一种众所周知的、有文档记录的和使用的方法。
如果您担心其他开发人员无法跟上进度,请添加指向 wikipedia 工厂的链接代码中的(xml)文档中的模式页面

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

The Factory pattern is a well known, documented, and used method.
If you're that concerned about other devs not being up-to-speed, then put a link to wikipedia's factory pattern page in the (xml) documentation in the code.

Also, make sure you name your Factories consisently - Microsoft seem to like the Provider suffix.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文