public class Factory
{
public static BaseClass Create(string name)
{
switch (name)
{
case "A": return new A();
case "B": return new B();
case "C": return new C();
default: throw new ArgumentException("Wrong Name");
}
}
}
新增子類必須修改工廠類,違反開閉原則。
[AttributeUsage(AttributeTargets.Class)]
public class FactoryKeyAttribute : Attribute
{
public object Key { get; set; }
}
public abstract class BaseClass { }
[FactoryKey(Key = "Standard")]
public class Standard : BaseClass { }
[FactoryKey(Key = "Enterprise")]
public class Enterprise : BaseClass { }
[FactoryKey(Key = "Lite")]
public class Lite : BaseClass { }
public class Factory<TKey, TBaseClass>
{
private static readonly IDictionary<TKey, Type> _typeMap = Init();
private static IDictionary<TKey, Type> Init()
{
return Assembly.GetExecutingAssembly().GetTypes()
.Where(t => typeof(TBaseClass).IsAssignableFrom(t) && !t.IsAbstract)
.Select(t => new
{
Key = (FactoryKeyAttribute)Attribute.GetCustomAttribute(t, typeof(FactoryKeyAttribute)),
Type = t
})
.Where(x => x.Key != null)
.ToDictionary(x => (TKey)x.Key.Key, x => x.Type);
}
public static TBaseClass CreateInstance(TKey key)
{
if (_typeMap.TryGetValue(key, out Type type))
return (TBaseClass)Activator.CreateInstance(type);
throw new ArgumentException($"Key '{key}' not registered");
}
}
BaseClass s = Factory<string, BaseClass>.CreateInstance("Standard");
BaseClass l = Factory<string, BaseClass>.CreateInstance("Lite");
BaseClass e = Factory<string, BaseClass>.CreateInstance("Enterprise");
// 支援 Enum Key
public enum Edition { Standard, Enterprise, Lite }
[FactoryKey(Key = Edition.Standard)] public class Standard : BaseClass { }
// Factory.CreateInstance(Edition.Standard);
Assembly[] 替代 GetExecutingAssembly()Activator.CreateInstance(type, args) 支援依賴注入Singleton/Scoped 生命週期CreateInstanceAsync 返回 Task<TBaseClass>Attribute 驅動工廠實現「約定優於配置」:新增實現類只需加 [FactoryKey],零修改工廠代碼。泛型設計支援任意 Key/基類類型,反射初始化僅在首次調用發生,效能影響可忽略。這是 .NET 中實現可擴展插件系統的經典模式。