在c#中使用反射的自注册工厂
发布时间:2020-12-15 22:18:20 所属栏目:百科 来源:网络整理
导读:我想对以下工厂的实施提出一些反馈意见: public enum DietType {Carnivore,Herbivore,Omnivore};[AttributeUsage(System.AttributeTargets.Class)]public class DietTypeAttribute : Attribute{ public DietType dietType { get; private set; } public Die
我想对以下工厂的实施提出一些反馈意见:
public enum DietType {Carnivore,Herbivore,Omnivore}; [AttributeUsage(System.AttributeTargets.Class)] public class DietTypeAttribute : Attribute { public DietType dietType { get; private set; } public DietTypeAttribute(DietType dietType) { this.dietType = dietType; } } public abstract class Diet { } [DietTypeAttribute(DietType.Carnivore)] public class Carnivore : Diet { } [DietTypeAttribute(DietType.Herbivore)] public class Herbivore : Diet { } abstract class AbstractFactory<T> where T : class { protected Dictionary<Enum,Type> types; protected AbstractFactory() { } public T CreateInstance(Enum id,params object[] param) { return (T)Activator.CreateInstance(types[id],param); } } class DietFactory : AbstractFactory<Diet> { public DietFactory() { types = (from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() let attributes = type.GetCustomAttributes(typeof(DietTypeAttribute),true) where (attributes.Any()) && (typeof(Diet).IsAssignableFrom(type)) && (type.IsClass) select new { dietEnum = (Enum)((DietTypeAttribute)attributes.First()).dietType,dietType = type }).ToDictionary(x => x.dietEnum,x => x.dietType); } } 用法: static void Main(string[] args) { AbstractFactory<Diet> factory = new DietFactory(); Diet diet = factory.CreateInstance(DietType.Carnivore); } 主要思想是使用枚举而不是字符串自行注册类.我正在努力找到一种方法使注册“通用”,所以我可以避免在LINQ查询上指定属性类. 欢迎任何帮助! 解决方法
试试这样的东西……
public enum DietType {Carnivore,Omnivore}; public class FactoryAttribute : Attribute { public Object Something { get; protected set; } } [AttributeUsage(System.AttributeTargets.Class)] public class DietTypeAttribute : FactoryAttribute { public DietTypeAttribute(DietType dietType) { this.Something = dietType; } } public abstract class Diet { } [DietTypeAttribute(DietType.Carnivore)] public class Carnivore : Diet { } [DietTypeAttribute(DietType.Herbivore)] public class Herbivore : Diet { } abstract class AbstractFactory<T> where T : class { protected Dictionary<Enum,Type> types; protected AbstractFactory() { } protected void Register<TEnumType,TSubType>() where TEnumType: FactoryAttribute { types = (from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() let attributes = type.GetCustomAttributes(typeof(TEnumType),true) where (attributes.Any()) && (typeof(TSubType).IsAssignableFrom(type)) && (type.IsClass) select new { dietEnum = (Enum)((TEnumType)attributes.First()).Something,x => x.dietType); } public T CreateInstance(Enum id,params object[] param) { return (T)Activator.CreateInstance(types[id],param); } } class DietFactory : AbstractFactory<Diet> { public DietFactory() { Register<DietTypeAttribute,Diet>(); } } 并测试…… void Main() { AbstractFactory<Diet> factory = new DietFactory(); Diet diet = factory.CreateInstance(DietType.Carnivore); //diet is a 'Carnivore' diet = factory.CreateInstance(DietType.Herbivore); //diet is a 'Herbivore' } 编辑: abstract class AbstractFactory<T> where T : class { protected Dictionary<Enum,Type> types; protected AbstractFactory() { types = (from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() let attributes = type.GetCustomAttributes(typeof(FactoryAttribute),true) where (attributes.Any()) && (typeof(T).IsAssignableFrom(type)) && (type.IsClass) select new { dietEnum = (Enum)((FactoryAttribute)attributes.First()).Something,param); } } 你的工厂很简单: class DietFactory : AbstractFactory<Diet> { public DietFactory() { } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |