gpt4 book ai didi

ninject - 如何使用 Ninject 约定扩展将泛型类型与继承绑定(bind)

转载 作者:行者123 更新时间:2023-12-05 00:31:12 30 4
gpt4 key购买 nike

如何绑定(bind)InitializerForXXX (非通用实现)到 IInitializer<XXX> (通用接口(interface))使用 Ninject Conventions以便请求 IInitializer<T>解析名称以 InitializerFor 开头并以 typeof(T).Name 结尾的非泛型实现像:

initializerFactory.CreateFor<Blue>();        //resolves InitializerOfBlue
initializerFactory.CreateFor<ShadeOfBlue>(); //resolves InitializerOfShadeOfBlue

没有非抽象类直接实现 IInitializer<T> ,并且一些实现继承自其他实现:
  • InitializerForShadeOfBlue继承自 InitializerForBlue
  • InitializerForBlue继承自抽象 Initializer<Blue>
  • 摘要 Initializer<T>直接实现IInitializer<T>

  • 我希望我可以使用 .EndsWith(typeof(T).Name)对于给定的 IInitializer<T>我可以使用约定,因为在 ShadeOfxxx 静脉中确实有数百个初始化程序。如果我必须映射所有这些,我最好找到一种在运行时通过反射解决的方法。

    鉴于以下情况:

    更新:使用自定义绑定(bind)生成器进行绑定(bind)(请参阅下面的答案以了解实现)

        void Bootstrap(IBindingRoot kernel)
    {
    kernel.Bind<IInitializerFactory>()
    .To<InitializerFactory>()
    .InSingletonScope();

    kernel.Bind(scanner =>
    scanner.FromThisAssembly().SelectAllClasses()
    .WhichAreNotGeneric()
    .InheritedFrom(typeof(IComplexContent))
    .BindAllInterfaces());

    kernel.Bind(scanner =>
    scanner.FromThisAssembly().SelectAllClasses()
    .WhichAreNotGeneric()
    .InheritedFrom(typeof(IInitializer<>))
    .BindWith<FirstTypeParameterNameMatchesEndOfBoundClassNameGenerator>());
    }

    主要方法

    void Main(IEnumerable<string> values)
    {
    // setup bindings
    var kernel = new StandardKernel();
    Bootstrap(kernel);

    IInitializerFactory initializerFactory =
    kernel.Get<IInitializerFactory>();

    IInitializer<ShadeOfBlueComplexContent> initializer =
    initializerFactory.CreateFor<ShadeOfBlueComplexContent>();

    initializer.Initialize(values);
    }

    初始化器工厂

    interface IInitializerFactory
    {
    IInitializer<T> CreateFor<T>() where T : class, IComplexContent, new();
    }

    class InitializerFactory : IInitializerFactory
    {
    public IInitializer<T> CreateFor<T>() where T : class, IComplexContent, new()
    {
    return MagicallyGetInitializer<T>();
    }

    //behind the curtain, whirring noises are heard as 't' is resolved...
    private static IInitializer<T> MagicallyGetInitializer<T>()
    where T : class, IComplexContent, new()
    {
    IInitializer<T> i = null;
    return i;
    }
    }

    初始化器

    interface IInitializer<out T> where T : IComplexContent
    {
    T Initialize(IEnumerable<string> values);
    }

    abstract class Initializer<T> : IInitializer<T> where T : IComplexContent
    {
    public abstract T Initialize(IEnumerable<string> values);
    }

    class InitializerOfBlue : Initializer<Blue>
    {
    private readonly Blue _content;

    public InitializerOfBlue(Blue content) {_content = content;}

    public override Blue Initialize(IEnumerable<string> values)
    {
    _content.BlueSpecificProperty = values.ElementAt(0);
    //... populate other blue-specific properties like this
    return _content;
    }
    }

    class InitializerOfShadeOfBlue : InitializerOfBlue
    {
    public InitializerOfShadeOfBlue(ShadeOfBlue content) : base(content){}
    }

    内容模型

    interface IComplexContent
    {
    string OneBasicProperty { get; set; }
    // other properties are specific to implementation
    string UniqueOperation();
    }

    abstract class BaseComplexContent : IComplexContent
    {
    public string OneBasicProperty { get; set; }
    public abstract string UniqueOperation();
    }

    class Blue : BaseComplexContent
    {
    // initializer sets this
    public string PropertyForAllKindsOfBlue { get; set; }

    // initializer doesn't interact with this
    public override string UniqueOperation() {return "I'm plain.";}
    }

    class ShadeOfBlue : Blue
    {
    // initializer doesn't interact with this
    public override string UniqueOperation() {return "I'm fabulous!";}
    }

    最佳答案

    您过度指定类(class)选择

        kernel.Bind(scanner =>
    scanner.FromThisAssembly().SelectAllClasses()
    .WhichAreNotGeneric()
    .InheritedFrom(typeof (IInitializer<>))

    这已经足够了。您需要做的是添加一个自定义绑定(bind)生成器。选择 IInitializer<Blue>对于 InitializerForBlueIInitializer<ShadeOfBlue>对于 InitializerForShadeOfBlue
    https://github.com/ninject/ninject.extensions.conventions/wiki/Projecting-Services-to-Bind

    关于ninject - 如何使用 Ninject 约定扩展将泛型类型与继承绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15259175/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com