gpt4 book ai didi

c# - 你如何在工厂中实现构造函数注入(inject)?

转载 作者:行者123 更新时间:2023-11-30 12:37:39 25 4
gpt4 key购买 nike

当您使用工厂模式时,如何在运行时将依赖项注入(inject)构造函数?

我正在构建具有不同格式的 Foos - bool 值、数组、自由文本、矩阵等。随着我们发现 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();
}
}

即便如此,他们也需要从我的抽象工厂派生一个工厂来满足他们的特定上下文。

我专门在 html 上下文中构建 foos,如下所示:

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 中注入(inject)一个空值列表。我希望能够传递来自消费者的值列表。对于其他 FooFormat,我想从消费者那里传递正确的构造函数参数。但我想让公共(public) API 保持简单——我不想在 BuildFoo() 上有一堆重载。

那么如何从 HtmlFooConsumer.DoSomeFoo() 内部将自定义值列表传递到 factory.BuildFoo () 调用中?有什么想法吗,stackoverflow 专家?

最佳答案

也许您可以按照这些思路做一些事情,其中​​您的抽象 FooFormat 变为 IFooFormat 并且通用 FooFormat 提供了一个传递参数的 Init 方法。

然后 Build 的单个重载允许您传入参数。

public interface IFooFormat
{
}

public class FooFormat<TValue> : IFooFormat
{
private TValue _value;

public void Init(TValue value)
{
_value = value;
}

public TValue Value
{
get { return _value; }
}
}

public class ArrayFooFormat : FooFormat<IList<string>> { }

public class BooleanFooFormat : FooFormat<bool> { }

public class DefaultFooFormat : IFooFormat { }

public interface IFoo { }

public class Foo : IFoo
{
private IFooFormat _format;

internal Foo(IFooFormat format)
{
_format = format;
}

public IFooFormat Format { get { return _format; } }
}

public class FooFactory
{
protected IFoo Build<TFormat, TArg>(TArg arg) where TFormat : FooFormat<TArg>, new()
{
TFormat format = new TFormat();
format.Init(arg);
return new Foo(format);
}

protected IFoo Build<TFormat>() where TFormat : IFooFormat, new()
{
return new Foo(new TFormat());
}
}

关于c# - 你如何在工厂中实现构造函数注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/373153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com