1 回答

TA貢獻1942條經驗 獲得超3個贊
考慮到問題評論,我建議有一個IStrategy接口并用于IEnumerable<Func<IStrategy>>注入策略工廠列表(這里為了簡潔起見我使用委托工廠,可以使用接口代替)。因此,我們可以將創建這樣一個列表與創建策略脫鉤:
static IEnumerable<IStrategy> CreateAll(this IEnumerable<Func<IStrategy>> factories) =>
factories.Select(factory => factory());
使用示例:
listOfStrategies.AddRange(
new Func<IStrategy>[]
{
() => new B(),
() => new C()
}).CreateAll()); // 2 items (`B` and `C`) will be added.
Func<IStrategy>如果方便的話,可以從類層次結構中創建策略工廠列表 ( ):
static IEnumerable<Func<IStrategy>> GetByBaseType<T>() =>
typeof(T)
.Assembly
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(T)) && t.GetInterface(nameof(IStrategy)) != null)
// We assume t has a parameterless constructor
.Select(t => (Func<IStrategy>)(() => (IStrategy)Activator.CreateInstance(t)));
一個樣品:
class A { }
class B : A, IStrategy { }
class C : A, IStrategy { }
創建策略工廠列表:
var factories = GetByBaseType<A>().ToList(); // Two `Func<IStrategy>` objects
var strategies = CreateAll(factories).ToList(); // Two `IStrategy` objects - `B` and `C`.
此外,通常返回的方法比接受并向其中添加項目的IEnumerable<T>方法更具可重用性和“純粹”性。List<T>
還有一件事 - 許多 DI 容器支持解析所有已注冊實現的列表。請參閱UnityContainer下面的示例:
var c = new UnityContainer()
.RegisterType<IStrategy, B>("B")
.RegisterType<IStrategy, C>("C");
// Two items - `B` and `C`.
c.Resolve<IEnumerable<IStrategy>>().ToList();
- 1 回答
- 0 關注
- 130 瀏覽
添加回答
舉報