本文提供一种简单的对象依赖注入解决方法,用于在类中根据特性依赖注入对于的对象,解放了手工new一个对象的劳力。本特性参考了Java Spring的依赖注入框架。
1、定义两个注解类型
/// <summary>
/// Bean注解,用于定义Bean,注解在类上
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class Bean : Attribute {
private String _value = "";
public Bean() {
}
public Bean(String value) {
this._value = value;
}
public string Value {
get {
return _value;
}
set {
_value = value;
}
}
}
/// <summary>
/// Resource注解,用于注解需要注入资源的变量
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class Resource : Attribute {
private String name = "";
public Resource() {
}
public Resource(String name) {
this.name = name;
}
public string Name {
get {
return name;
}
set {
name = value;
}
}
}
2、注解解析类
/// <summary>
/// 简单注解框架<br>
/// by yanhang0610
/// </summary>
public class SimpleAnnotation {
// 存储扫描到的使用Bean注解的类Class
private static Dictionary<String, Type> beanClasses = new Dictionary<String, Type>();
private SimpleAnnotation() {
}
/**
* 扫描程序集里添加了Bean注解的类
* @param pakageNames 包名全路径,可以有多个,多个的话用英文半角逗号","分隔
*/
public static void ScanBeans() {
try {
SimpleAnnotation.beanClasses.Clear();
Type[] classes = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type clazz in classes) {
// 判断Bean注解的class
Object[] attrs = clazz.GetCustomAttributes(typeof(Bean), false);
if (attrs != null && attrs.Length > 0) {
Bean attribute = attrs[0] as Bean;
CollectionUtils.PutKeyValueToDic<String, Type>(SimpleAnnotation.beanClasses, attribute.Value, clazz);
}
}
} catch (Exception e) {
LoggerUtils.RecordInfoAndDebugMessage(e, " 扫描Bean注解类出错!");
}
}
/// <summary>
/// 依赖注入<br>
/// 将obj里添加了Resource注解的字段注入Resource name值对应的Bean对象,Resouce name值等于Bean value值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
public static void DependencyInject<T>(T obj) {
try {
Type clazz = typeof(T);
FieldInfo[] fields = clazz.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields) {
Object[] attrs = field.GetCustomAttributes(typeof(Resource), false);
if (attrs != null && attrs.Length > 0) {
Resource attribute = attrs[0] as Resource;
field.SetValue(obj, GetBeanInstance<Object>(attribute.Name));
}
}
} catch (Exception e) {
LoggerUtils.RecordInfoAndDebugMessage(e, "依赖注入Bean对象出错!");
}
}
/// <summary>
/// 获取添加了Bean注解的类class
/// </summary>
/// <param name="name">Bean注解的name属性</param>
/// <returns></returns>
public static Type GetBeanClass(String name) {
return CollectionUtils.GetDicValue<String, Type, Type>(SimpleAnnotation.beanClasses, name);
}
/// <summary>
/// 获取添加了Bean注解的类class的实例,多例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name">Bean注解的name属性</param>
/// <returns></returns>
public static T GetBeanInstance<T>(String name) {
Type clazz = GetBeanClass(name);
return clazz == null ? default(T) : (T) Activator.CreateInstance(clazz);
}
}
3、使用示例
public partial class CompanyInfoWindow : Window { private ILog baseLogger = SysLoggerManager.GetBaseLogger(); [Resource(Name = "companyService")] private ICompanyService companyService; public CompanyInfoWindow() { InitializeComponent(); SimpleAnnotation.DependencyInject(this); }
}
/** * Company Service * @author E-mail: yanhang0610@qq.com * Create Time:2016-10-15 18:40:39 */ [Bean("companyService")] public class CompanyServiceImpl : ICompanyService { }