c# – 如何在工厂中实现构造函数注入?
发布时间:2020-12-15 22:56:23 所属栏目:百科 来源:网络整理
导读:当您使用工厂模式时,如何在运行时将依赖项注入构造函数? 我正在构建具有不同格式的Foos – 布尔,数组,自由文本,矩阵等.当我们发现Foo的不同用途时,格式列表将会增长.这是我的基本核心领域: public interface IFoo{ FooFormat Format { get; }}public class
当您使用工厂模式时,如何在运行时将依赖项注入构造函数?
我正在构建具有不同格式的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(); } } 即便如此,他们还需要从我的抽象工厂中获取一个工厂用于他们的特定背景. 我特意在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中注入一个空值列表.我希望能够传递消费者的价值表.对于其他FooFormats,我想从使用者传递正确的构造函数参数.但我想让公共API变得简单 – 我不想在BuildFoo()上出现一堆重载. 那么如何将自定义值列表传递到来自HtmlFooConsumer.DoSomeFoo()内部的factory.BuildFoo< T>()调用?任何想法,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()); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |