如何将InitializerForXXX(非泛型实现)绑定到IInitializer XXX (通用接口)使用 Ninject Conventions以便请求IInitializer T解析名称以InitializerFor开头并以typeof(T).Name结尾的非泛型实现,如: initializerFactory
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