如何将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
