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

问题描述

假设我有一些类Foo,它有两个依赖关系:一个ISerializer和一个IFileAccessHandler。



现在这个类还有其他依赖关系,功能依赖。我不想让任何实例化这个类处于无效状态,所以我还需要在构造函数中传递一个域对象。但是,当我也知道在实际创建Foo类的时候,我还知道要传递什么域对象吗?



$ b


$ b

我将域对象设置为由工厂设置的属性。所以工厂做一个服务定位器调用,以获得一个适当的实例化的Foo类的依赖关系,并进一步填充正确的域对象并返回。



但这是最好的方式吗?我会喜欢让我的构造函数的域对象部分使其成为你实际需要使用Foo。



任何想法?
我在这里缺少什么?
Thx提前!

解决方案

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



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

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

这将允许您定义一个了解您的基础架构服务的具体实现。

  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)
{
返回新的Foo(this.serializer,this.fileHandler,dc);
}
}

这样,您可以保护不变量



在DI容器中,您可以注册IFooFactory和相应的实施。你有一个DomainClass实例,需要一个Foo实例,然后你将依赖于IFooFactory并使用它。


Just assume I have some class Foo, that has two dependencies: an ISerializer 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 prefered 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? Thx in advance!

解决方案

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.

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

10-30 06:37