【问题标题】:Ninject: Default & specific bindings for a Generic classNinject:通用类的默认和特定绑定
【发布时间】:2011-06-02 19:45:56
【问题描述】:

我有一个抽象类:

 public abstract class Validator<T> : IValidator

以及一些为特定目的实现此类的类,例如

public sealed class NewsValidator : Validator<News>

现在使用 Ninject 我想做如下的依赖注入(这个特定的代码不起作用):

Bind<Validator<News>>().To<NewsValidator>();
Bind(typeof(Validator<>)).To(typeof(NullValidator<>));

所以我想要实现的是

Validator<News>

应该绑定到“NewsValidator”类,但如果请求了该类的任何其他未绑定版本,请说

Validator<Article>
Validator<SomethingElse>

应该绑定到默认类(NullValidator)。但是,使用上面使用的代码会引发异常,因为它将 Validator 绑定到 NewsValidator 以及 NullValidator。

我该如何实现呢?泛型类的特定类型应绑定到各个类。没有显式绑定的所有其他类型的泛型类都应该绑定到默认类。

如果有几个建议会很高兴!谢谢!

【问题讨论】:

    标签: c# asp.net-mvc-3 ninject ninject-2


    【解决方案1】:

    您可以创建IMissingBindingResolver 的自定义实现。

    每当内核无法解析所请求服务的绑定时,它都会委托给HandleMissingBinding 方法(对于从KernelBase 派生的任何内核都是如此)。 HandleMissingBinding 方法将询问每个丢失的绑定解析器是否可以为请求的服务创建绑定。解析器返回的绑定(如果有)将被添加到内核中。

    请注意,任何由缺少绑定解析器创建的绑定都将作为隐式绑定添加到内核中。这可能会对您的应用程序产生影响。例如,如果您有一个服务的显式和隐式绑定的混合,解析这些绑定,即kernel.GetAll&lt;TService&gt;(),只会解析显式绑定。但是,如果所有绑定都是隐式的,它们都将被解析。

    Ninject 有两个标准的 IMissingBindingResolver 实现:

    让我们为空验证器实现一个自定义解析器。

    public class MissingValidatorResolver : NinjectComponent, IMissingBindingResolver
    {
        public IEnumerable<IBinding> Resolve(
            Multimap<Type, IBinding> bindings, IRequest request)
        {
            var service = request.Service;
            if (!typeof(IValidator).IsAssignableFrom(service))
            {
                return Enumerable.Empty<IBinding>();
            }
    
            var type = service.GetGenericArguments()[0];
            var validatorType = typeof(NullValidator<>).MakeGenericType(type);
    
            var binding = new Binding(service)
            {
                ProviderCallback = StandardProvider.GetCreationCallback(validatorType)
            };
    
            return new[] { binding };
        }
    }
    

    现在下面的测试(使用xUnit.net)通过了。

    [Fact]
    public void ShouldResolveNonBoundValidatorDerivedFromValidatorAsNullValidator()
    {
        var kernel = new StandardKernel();
        kernel.Components.Add<IMissingBindingResolver, MissingValidatorResolver>();
    
        var validator = kernel.Get<Validator<Article>>();
        Assert.IsType<NullValidator<Article>>(validator);
    }
    

    【讨论】:

    • 哇 :) 令人难以置信,一个人的工作就像一个魅力。你怎么知道的?!在搜索“IMissingBindingResolver”时,即使是谷歌也没有真正找到很多。无论如何,这绝对是完美的,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 2019-07-30
    • 2011-04-10
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多