首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 通用泛型工廠模式:Attribute 驅動的零配置實現

     編輯:關於.NET

痛點:傳統工廠需修改代碼擴展

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");
        }
    }
}

新增子類必須修改工廠類,違反開閉原則。

解決方案:Attribute + 反射自動註冊

1. 定義標記 Attribute

[AttributeUsage(AttributeTargets.Class)]
public class FactoryKeyAttribute : Attribute
{
    public object Key { get; set; }
}

2. 標記實現類

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 { }

3. 通用泛型工廠實現

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");
    }
}

4. 使用示例

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 中實現可擴展插件系統的經典模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved