当前位置 : 主页 > 手机开发 > 其它 >

如何使用Ninject Conventions扩展将泛型类型与继承绑定

来源:互联网 收集:自由互联 发布时间:2021-06-19
如何将InitializerForXXX(非泛型实现)绑定到IInitializer XXX (通用接口)使用 Ninject Conventions以便请求IInitializer T解析名称以InitializerFor开头并以typeof(T).Name结尾的非泛型实现,如: initializerFactory
如何将InitializerForXXX(非泛型实现)绑定到IInitializer< XXX> (通用接口)使用 Ninject Conventions以便请求IInitializer< T>解析名称以InitializerFor开头并以typeof(T).Name结尾的非泛型实现,如:

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

其中没有非抽象类直接实现IInitializer< T>,而某些实现继承自其他实现:

> InitializerForShadeOfBlue继承自InitializerForBlue
> InitializerForBlue继承自抽象初始化器< Blue>
>抽象初始化器< T>直接实现IInitializer< T>

我希望我能为给定的IInitializer< T>使用.EndsWith(typeof(T).Name).我可以使用的约定,因为ShadeOfxxx静脉中有数百个初始值设定项.如果我必须映射所有这些,我最好找到一种在运行时使用反射解决的方法.

鉴于以下内容:

更新:与自定义绑定生成器的绑定(请参阅下面的答案以实现)

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!";}
}
你完成了指定类选择

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

这已经足够了.您需要做的是添加自定义绑定生成器.选择IInitializer< Blue> for InitializerForBlue和IInitializer< ShadeOfBlue> for InitializerForShadeOfBlue

https://github.com/ninject/ninject.extensions.conventions/wiki/Projecting-Services-to-Bind

网友评论