After some searching of examples , I have written this solutions. I do
not know is it the best solution, but any way it is works for me. If
somebody will improve my code or write best practice for my question I
will be grateful :-)
UnitTest Where I want get type which Inherited From IStepContext,
which have 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));
}
}
Custom 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;
}
}
Helper Classes
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;
}
}