日期:2014-05-20  浏览次数:20763 次

依赖注入的问题谢谢回答
C# code

[AttributeUsage(AttributeTargets.Class), AllowMultiple=true]
sealed class DecoratorAttribute : Attribute
{
    public readonly object Injector;
    private Type type;
 
    public DecoratorAttribute(Type type)
    {
        if (type == null) throw new ArgumentNullException("type");
        this.type = type;
        Injector = (new Assembler()).Create(this.type);
    }
 
    public Type Type { get { return this.type; } }
}
 
static class AttributeHelper
{
    public static T Injector(object target)//[color=#FF0000]这个泛型怎么解释我不太懂[/color]
        where T : class
    {
        if (target == null) throw new ArgumentNullException("target");
        Type targetType = target.GetType();
        object[] attributes = targetType.GetCustomAttributes(
            typeof(DecoratorAttribute), false);
        if ((attributes == null) || (attributes.Length <= 0)) return null;
        foreach (DecoratorAttribute attribute in
            (DecoratorAttribute [])attributes)
            if (attribute.Type == typeof(T))// if (attribute.Type.GetInterfaces().Contains(typeof(T)))
                return (T)attribute.Injector;
        return null;
    }
}
 
[Decorator(typeof(ITimeProvider)]//[color=#FF0000]这里应该使用可实例化的类吧,不应该使用接口吧[/color]
class Client
{
    public int GetYear()
    {
        ITimeProvider provider =
            AttributeHelper.Injector(this);
        return provider.CurrentDate.Year;
    }
}





这段代码是依赖注入。使用Attribute把外部对接口的实现注入到类中。通过修改Attribute来改变依赖。
其中第29行和第35行中,有一个明显的错误。
先从第35行说起
[Decorator(typeof(ITimeProvider)]
这行代码说明要注入ITimeProvider类型,但是我们知道接口是不能被直接实例化的。所以这里的ITimeProvider应该改成TimeProvider。
但是这个时候第29行的条件判断就出现问题了,因为我们要得到的是ITimeProvider,而Decorator给的参数是TimeProvider,这两个类型是不会相等的。
这个时候我们还必须修改第29行的代码为
if (attribute.Type.GetInterfaces().Contains(typeof(T)))
通过寻找实现接口的实例,才能够真正找到我们要的Decorator。



------解决方案--------------------
[Decorator(typeof(ITimeProvider)] 

这里定义接口是没错的。DI通过接口引入外部实现,思想没错。

关键在于:(new Assembler()).Create(this.type);

是怎么实现的 Create 方法。里面应该有真正引入外部实例的地方。