NInject 的上下文绑定

Contextualized bindings with NInject

我有一个接口 IInterface,以及两个实现 Impl1Impl2

每个实现都用 KeyAttribute:

注释
[Key("key1")]
public class Impl1 : IInterface {}

[Key("key2")]
public class Impl2 : IInterface {}

Impl1 在一个程序集中,Impl2 在另一个程序集中。

我按照惯例创建绑定:

this.Bind(b => b.FromAssembliesMatching("*")
            .SelectAllClasses()
            .InheritedFrom(typeof(IInterface))
            .BindAllInterfaces()
        );

通过配置,我的项目有一个类似于 <user, backend> 列表的配置,其中 backend 是将关联的后端密钥。

当我加载用户配置时,我需要 Get 实现关联 implementation.KeyAttribute.Equals(currentUser)

有什么想法吗?

您可以使用 Configure 方法创建命名绑定:

kernel.Bind(x => x
    .FromThisAssembly()
    .SelectAllClasses()
    .InheritedFrom<IInterface>()
    .BindAllInterfaces()
    .Configure((syntax, type) => syntax.Named(GetKeyFrom(type))));

private static string GetKeyFrom(Type type)
{
    return type
        .GetCustomAttributes(typeof(KeyAttribute), false)
        .OfType<KeyAttribute>()
        .Single()
        .Key;
}

然后解决它:

kernel.Get<IInterface>("key1");
kernel.Get<IInterface>("key2");

这是我的所有代码(用于验证目的):

using System;
using System.Linq;
using FluentAssertions;
using Ninject;
using Ninject.Extensions.Conventions;
using Xunit;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class KeyAttribute : Attribute
{
    public KeyAttribute(string key)
    {
        Key = key;
    }

    public string Key { get; private set; }
}

public interface IInterface { }

[Key("key1")]
public class Impl1 : IInterface { }

[Key("key2")]
public class Impl2 : IInterface { }

public class Test
{
    [Fact]
    public void Foo()
    {
        var kernel = new StandardKernel();
        kernel.Bind(x => x
            .FromThisAssembly()
            .SelectAllClasses()
            .InheritedFrom<IInterface>()
            .BindAllInterfaces()
            .Configure((syntax, type) => syntax.Named(GetKeyFrom(type))));

        kernel.Get<IInterface>("key1").Should().BeOfType<Impl1>();
        kernel.Get<IInterface>("key2").Should().BeOfType<Impl2>();
    }

    private static string GetKeyFrom(Type type)
    {
        return type
            .GetCustomAttributes(typeof(KeyAttribute), false)
            .OfType<KeyAttribute>()
            .Single()
            .Key;
    }
}