代码修正#
FromServiceAttribute#
完好的代码修正可以参考这个 commit https://github.com/WeihanLi/WeihanLi.Common/commit/91dc0b515d12e7c036771fba9419824cd0219544
首先我们需求增加一个 FromServiceAttribute 用来标识哪些属性需求注入,代码如下:
Copy
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public sealed class FromServiceAttribute : Attribute
{
}
这里 AttributeTargets 除了属性之外增加了字段和参数,是想可能以后会用到,参数典型的应用场景就是类似于 asp.net core 里的 [FromServices] 用来完成方法注入参数
EnrichObject#
增加了一个 EnrichObject 方法,用来在获取到效劳实例之后,对效劳实例做一些补充的配置,如我们要加的属性注入,假设我们要加字段注入等也可以在这个方法内完成,来看完成:
Copy
private object EnrichObject(object obj)
{
if (null != obj)
{
// PropertyInjection
var type = obj.GetType();
foreach (var property in CacheUtil.TypePropertyCache.GetOrAdd(type, t => t.GetProperties())
.Where(x => x.IsDefined(typeof(FromServiceAttribute))))
{
if (property.GetValueGetter()?.Invoke(obj) == null)
{
property.GetValueSetter()?.Invoke(
obj,
GetService(property.PropertyType)
);
}
}
}
return obj;
}
上面的逻辑就是获取这个 object 定义的一切需求注入的属性,假设属性的值不为 null 则,从效劳容器中获取对应的效劳实例,之所以要检查是不是null
上面的 CacheUtil.TypePropertyCache 是一个 Type 为 key,PropertyInfo 数组为 Value 的并发字典,用来缓存类型的属性
GetValueGetter/GetValueSetter 是 PropertyInfo 的扩展方法,应用表达式树缓和存进步属性 Get/Set 的效率
GetSertviceInstance#
修正原来的 GetServiceInstance 方法为 GetServiceInstanceInternal,增加一个一样的方法,完成逻辑是在 GetServiceInstanceInternal 的基础上调用上面的 Enrich 方法来完成属性注入
More#
固然增加了属性注入的支持,但是还是不太举荐运用,从上面属性注入的代码中可以看得到,假设用不好很容易呈现循环依赖的问题,而且用构造器注入的话依赖关系很明晰,分析方法的构造方法即可,假设要运用属性注入请谨慎运用
Reference#
https://github.com/WeihanLi/WeihanLi.Common/commit/91dc0b515d12e7c036771fba9419824cd0219544
https://github.com/WeihanLi/WeihanLi.Common/tree/dev/src/WeihanLi.Common/DependencyInjection
https://www.cnblogs.com/weihanli/p/implement-dependency-injection.html
https://www.cnblogs.com/weihanli/p/implement-dependency-injection-01.html
https://www.cnblogs.com/weihanli/p/implement-dependency-injection-02.html