나는 IInitializer<XXX>
(범용 인터페이스)을 (제네릭이 아닌 구현)을 IInitializer<T>
요청 이름이 시작하는 제네릭이 아닌 구현을 해결할 수 있도록 Ninject Conventions를 사용하여 InitializerForXXX
을 결합 할 수있는 방법 같은 typeof(T).Name
와 InitializerFor 과 끝 :는 어떻게해서 Ninject 규칙 확장을 사용하여 상속 제네릭 형식을 결합 할
initializerFactory.CreateFor<Blue>(); //resolves InitializerOfBlue
initializerFactory.CreateFor<ShadeOfBlue>(); //resolves InitializerOfShadeOfBlue
더 비 추상 클래스는 직접 IInitializer<T>
을 구현없는 경우, 일부 구현은 다른 구현에서 상속 :
Initializer<Blue>
Initializer<T>
에서 InitializerForBlue
InitializerForBlue
상속에서
InitializerForShadeOfBlue
상속은 직접 내가 때문에, 내가 사용할 수있는 주어진IInitializer<T>
규칙에 대한.EndsWith(typeof(T).Name)
를 사용할 수 바라고 있어요IInitializer<T>
를 구현 글자 그대로 ShadeOfxxx 정맥에는 수백 개의 초기화자가 있습니다. 모든 것을 매핑해야한다면 런타임시 반영으로 해결할 방법을 찾는 것이 좋습니다.
다음 감안할 때 :
UPDATE : 사용자 정의 바인딩 생성기 바인딩은
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);
}
초기화 공장
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>());
}
주요 방법 (구현에 대한 내 대답은 아래 참조)
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!";}
}
좋아, 나는 그에서 자상을 가지고 업데이 트를 게시합니다. 이를 위해 AbstractInterfaceBindingGenerator를 상속하거나 IBindingGenerator를 구현하는 것이 더 좋습니다. 나는 기존의 것들이/또는 어느 쪽인지를한다. – Jeff
는 –