После некоторого поиска примеров, я написал это решение. Я делаю Не знаю, это лучшее решение, но так или иначе оно работает для меня. Если кто-то улучшить свой код или написать наилучшую практику для моего вопроса я буду благодарен :-)
UnitTest Где я хочу получить тип, который наследуемых от IStepContext, которые имеют MarkAttribute
[TestClass]
public class Test
{
private readonly IKernel _kernel = new StandardKernel();
[TestInitialize]
public void Startup()
{
_kernel.Bind(a =>
{
a.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<IStepContext>()
.WithAttribute<MarkAttribute>(x => x.Type == Inheritance.Derived).BindWith<SettingsBindGenerator>();
});
}
[TestMethod]
public void BaseClass()
{
BaseClass1 derived1 = _kernel.Get<BaseClass1>();
Type res = derived1.WhoIAm(); //-- - > "BaseClass1"
Assert.AreEqual(res, typeof (BaseClass1));
}
[TestMethod]
public void DerivedClass()
{
IStepContextA derived = _kernel.Get<IStepContextA>();
Type res = derived.WhoIAm(); //-- - > "DerivedClass"
Assert.AreEqual(res, typeof (DerivedClass));
}
[TestMethod]
public void DerivedClassA1()
{
IStepContext derived2 = _kernel.Get<BaseClassA>();
Type res = derived2.WhoIAm(); //-- - > "DerivedClass"
Assert.AreEqual(res, typeof (DerivedClassA1));
}
}
Пользовательские BindGenerator
public class SettingsBindGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
Func<Type, IBindingWhenInNamedWithOrOnSyntax<object>> func =
t => bindingRoot.Bind(t).ToMethod(ctx => GetInstance(ctx, type));
var bindings = new List<IBindingWhenInNamedWithOrOnSyntax<object>>();
// if type inherited from interface
Type[] interfs = type.GetInterfaces();
if (interfs.Length > 1)
{
// skip base interface (IStepContext)
interfs = interfs.Take(interfs.Length - 1).ToArray();
bindings = interfs.Select(x => func(x)).ToList();
}
// if type inherited from baseType
Type baseType = type.BaseType;
if (baseType != null)
{
bindings.Add(func(baseType));
if (ShouldBeBound(baseType))
{
var ancestor = baseType.BaseType;
while (ancestor != null && ShouldBeBound(ancestor))
{
bindings.Add(func(ancestor));
ancestor = ancestor.BaseType;
}
}
}
return bindings;
}
private static bool ShouldBeBound(Type type)
{
return type.IsClass && type != typeof (object);
}
private object GetInstance(IContext ctx, Type type)
{
MethodInfo method = typeof(PageService).GetMethod("Create");
IPage page = method.MakeGenericMethod(type).Invoke(null, new object[] { null });
return page;
}
}
Вспомогательные классы
public class BaseClass : AbstractStepContext
{
public override Type WhoIAm()
{
return GetType();
}
}
public class AbstractStepContext : IStepContext
{
public virtual Type WhoIAm()
{
return GetType();
}
}
public class BaseClass1 : IBase
{
public virtual Type WhoIAm()
{
return GetType();
}
}
[Mark(Inheritance.Base)]
public class BaseClass1Derivied : BaseClass1
{
public override Type WhoIAm()
{
return GetType();
}
}
public class BaseClassA : AbstractStepContext
{
public virtual Type WhoIAm()
{
return GetType();
}
}
[Mark(Inheritance.Derived)]
public class DerivedClass : IStepContextA
{
public Type WhoIAm()
{
return GetType();
}
}
[Mark(Inheritance.Derived)]
public class DerivedClassA1 : BaseClassA
{
public override Type WhoIAm()
{
return GetType();
}
}
public interface IStepContext
{
Type WhoIAm();
}
public interface IStepContextA : IStepContext
{
}
public class MarkAttribute : Attribute
{
public Inheritance Type ;
public MarkAttribute(Inheritance type)
{
Type = type;
}
}
Здравствуйте @BatteryBackupUnit ** Этот код не компилировать **. Первая ошибка .BindWith, потому что MyBindingGenerator должен унаследовать от IBindingGenerator И следующая ошибка есть .Bind (serviceTypes) –
@ValeraFedorenko не можете ли вы попробовать еще раз? – BatteryBackupUnit
** все еще не скомпилирован ** посмотреть скриншот http://take.ms/SrZjn. Поскольку CreateBindings не имеет такой тип перегрузки с IEnumerable> CreateBindings ( IBindingRoot bindingRoot, IEnumerable serviceTypes, Тип ImplementationType) –