首页 / C# / 在c#中使用反射的自注册工厂
在c#中使用反射的自注册工厂
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了在c#中使用反射的自注册工厂,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3736字,纯文字阅读大概需要6分钟。
内容图文
我想对以下工厂的实施提出一些反馈意见:
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, Herbivore, 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,
dietType = type
}).ToDictionary(x => x.dietEnum, 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,
dietType = type
}).ToDictionary(x => x.dietEnum, x => x.dietType);
}
public T CreateInstance(Enum id, params object[] param)
{
return (T)Activator.CreateInstance(types[id], param);
}
}
你的工厂很简单:
class DietFactory : AbstractFactory<Diet>
{
public DietFactory()
{
}
}
内容总结
以上是互联网集市为您收集整理的在c#中使用反射的自注册工厂全部内容,希望文章能够帮你解决在c#中使用反射的自注册工厂所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。