不能结合工厂/DI [英] Can't combine Factory / DI

查看:12
本文介绍了不能结合工厂/DI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 Foo 类,它有两个依赖项:一个 ISerializer 和一个 IFileAccessHandler.

现在这个类还有其他的依赖,函数依赖.我不希望任何人在无效状态下实例化这个类,所以我还需要在构造函数中传递一个域对象.

但是,当我还知道在实际创建类 Foo 时要传递的域对象时,我如何让 IoC 处理它?<​​/p>

我将域对象设为由工厂设置的属性.因此,工厂调用 Service Locator 以获取正确实例化的Foo"类及其依赖项,并进一步用正确的域对象填充并返回它.

但这是最好的方法吗?我宁愿让我的构造函数的域对象部分使它看起来你实际上需要使用Foo".

有什么想法吗?我在这里遗漏了什么吗?

解决方案

在注册时无法连接具体类型时,DI 的默认解决方案是使用抽象工厂>

在你的情况下,我会定义一个 IFooFactory 接口:

公共接口 IFooFactory{Foo 创建(域类 dc);}

这将允许您定义一个了解您的基础设施服务的具体实现.

公共类 FooFactory : IFooFactory{私有只读 ISerializer 序列化程序;私有只读 IFileAccessHandler fileHandler;公共 FooFactory(ISerializer 序列化程序,IFileAccessHandler fileHandler){如果(序列化器 == 空){throw new ArgumentNullException("serializer");}如果(文件处理器 == 空){throw new ArgumentNullException("fileHandler");}this.serializer = 序列化器;this.fileHandler = fileHandler;}公共 Foo 创建(域类 dc){返回新的 Foo(this.serializer, this.fileHandler, dc);}}

通过这种方式,您可以保护 Foo 类的不变量,使您能够继续使用构造函数注入.

在DI容器中,可以注册IFooFactory和对应的实现.在任何有 DomainClass 实例并需要 Foo 实例的地方,您都可以依赖 IFooFactory 并使用它.

Just assume I have some class Foo, that has two dependencies: an ISerializer<T> and an IFileAccessHandler.

Now this class also has other dependencies, functional dependencies. I don't want anyone instantiating this class in an invalid state, so I'd also need to pass a domain object in the constructor.

But how can I have that handled by IoC when I also know what domain object to pass in the moment I'm actually creating class Foo?

I made the domain object a property that I have set by a Factory. So the Factory makes a Service Locator call to get a properly instantiated "Foo" class with it's dependencies, and further fills it up with the correct domain object and returns it.

But is this the best way to go? I would have preferred having the domain object part of my constructor to make it apparant you actually need to work with "Foo".

Any ideas? Am I missing something here?

解决方案

The default solution to DI when you can't wire up a concrete type at registration time is to use an Abstract Factory

In your case, I would define an IFooFactory interface:

public interface IFooFactory
{
    Foo Create(DomainClass dc);
}

This will allow you to define a concrete implementation that knows about your infrastructure services.

public class FooFactory : IFooFactory
{
    private readonly ISerializer serializer;
    private readonly IFileAccessHandler fileHandler;

    public FooFactory(ISerializer serializer, IFileAccessHandler fileHandler)
    {
        if(serializer == null)
        {
            throw new ArgumentNullException("serializer");
        }
        if(fileHandler == null)
        {
            throw new ArgumentNullException("fileHandler");
        }

        this.serializer = serializer;
        this.fileHandler = fileHandler;
    }

    public Foo Create(DomainClass dc)
    {
        return new Foo(this.serializer, this.fileHandler, dc);
    }
}

In this way you can protect the invariants of your Foo class, enabling you to stay with Constructor Injection.

In the DI container, you can register the IFooFactory and corresponding implementation. Everywhere you have a DomainClass instance and need a Foo instance, you would then take a dependency on IFooFactory and use that.

这篇关于不能结合工厂/DI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆