当您使用工厂模式时,如何在运行时注入依赖到构造函数中?你如何在工厂实现构造函数注入?
我正在构建不同格式的Foos - 布尔,数组,自由文本,矩阵等等。当我们发现Foo的不同用途时,这个格式列表将会增长。这里是我的基本的核心领域:
public interface IFoo
{
FooFormat Format { get; }
}
public class Foo : IFoo
{
private FooFormat _format;
internal Foo(FooFormat format)
{
_format = format;
}
public FooFormat Format { get { return _format; } }
}
public abstract class FooFormat
{
}
public class DefaultFooFormat : FooFormat
{
}
public class BooleanFooFormat : FooFormat
{
public IList<bool> Values { get; set; }
}
public class ArrayFooFormat : FooFormat
{
private IList<string> _values;
public ArrayFooFormat(IList<string> values)
{
_values = values;
}
public IList<string> Values { get { return _values; } }
}
IFoo的装饰为消费者方面:
public abstract class FooDecorator : IFoo
{
private IFoo _foo;
protected FooDecorator(IFoo foo)
{
_foo = foo;
}
public FooFormat Format
{
get { return _foo.Format; }
}
protected IFoo foo
{
get { return _foo; }
}
}
我不希望我的消费者直接实例化一个Foo,所以我强迫他们使用一个工厂:
public abstract class FooFactory
{
protected IFoo Build<T>()
{
FooFormat format = GetFormat<T>();
return new Foo(format);
}
private FooFormat GetFormat<T>()
{
if (typeof(T) == typeof(ArrayFooFormat)) return new ArrayFooFormat(new List<string>());
if (typeof(T) == typeof(BooleanFooFormat)) return new BooleanFooFormat();
return new DefaultFooFormat();
}
}
即使这样,他们需要从我的抽象工厂获得一个工厂的特定语境。
我专门构建的Foo在HTML中的上下文,像这样:
public class HtmlFoo : FooDecorator
{
public HtmlFoo(IFoo foo) : base(foo) { }
public string ToHtml()
{
return "<div>" + this.Format.ToString() + "</div>";
}
}
public class HtmlFooFactory : FooFactory
{
public IFoo BuildFoo<T>()
{
IFoo foo = Build<T>();
return new HtmlFoo(foo);
}
}
public class HtmlFooConsumer
{
public void DoSomeFoo()
{
var factory = new HtmlFooFactory();
var htmlBooleanFoo = factory.BuildFoo<BooleanFooFormat>();
var htmlArrayFoo = factory.BuildFoo<ArrayFooFormat>();
}
}
我的问题是在我的抽象FooFactory:我一直在注入空值列表进入我的ArrayFooFormat。我希望能够通过消费者的价值清单。对于其他FooFormats,我想从消费者传入正确的构造函数参数。但我想保持公共API的简单 - 我不想在BuildFoo()上做一堆重载。
那么如何将自定义值列表传入factory.BuildFoo <T>()调用来自HtmlFooConsumer.DoSomeFoo()?任何想法,stackoverflow大师?
在这样复杂的问题,它真的有助于有一个更真实的例子 - 而不是一堆Foo-ey。 – Bryan 2008-12-17 15:37:38