2

这是我想做的事情:

public interface IInject<in T>
{
    [Inject]
    void Inject(T reference);
}

private class Foo : IInject<Bar>
{
    public Bar Bar { get; private set; }

    void IInject<Bar>.Inject(Bar reference)
    {
        Bar = reference;
    }
}

但是没有任何东西被注入,我开始工作的唯一方法是使用属性和隐式实现:

private class Foo : IInject<Bar>
{
    public Bar Bar { get; private set; }

    [Inject]
    public void Inject(Bar reference)
    {
        Bar = reference;
    }
}

有没有办法做到这一点?

4

1 回答 1

2

默认情况下,Ninject 的行为并非如此。您将需要创建一个自定义选择器。*

给定您的类型,此选择器表现出您所描述的行为,

class ExplicitSelector : Selector
{
    public ExplicitSelector(
        IConstructorScorer constructorScorer, 
        IEnumerable<IInjectionHeuristic> injectionHeuristics) 
        : base(constructorScorer, injectionHeuristics)
    {
    }

    public override IEnumerable<MethodInfo> SelectMethodsForInjection(Type type)
    {
        // Gets all implemented interface and grabs an InterfaceMapping. 
        var implementedInterfaces = type.GetInterfaces();

        foreach (var map in implementedInterfaces.Select(type.GetInterfaceMap))
        {
            for (var i = 0; i < map.InterfaceMethods.Length; i++)
            {
                // Check each interface method for the Inject attribute, and if present
                if (map.InterfaceMethods[i].CustomAttributes.Any(x => x.AttributeType == typeof (InjectAttribute)))
                {
                    // return the target method implementing the interface method. 
                    yield return map.TargetMethods[i];
                }
            }
        }

        // Defer to NInject's implementation for other bindings. 
        foreach (var mi in base.SelectMethodsForInjection(type))
        {
            yield return mi;
        }
    }
}

它被简单地添加到内核中,

standardKernel.Components.Remove<ISelector, Selector>();
standardKernel.Components.Add<ISelector, ExplicitSelector>();

然后调用 get anIInject<Bar>将按照您的描述工作,使用自定义选择器。


*使用 NInject 实现这一点可能有更好的扩展点。我远不是 NInject 或其实施方面的专家。

于 2016-11-26T18:31:15.947 回答