Reputation: 99
example of convention extension
kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.WithAttribute<SomeAttribute>()
.BindBase();
});
And each type which I get should be provide complex initiation with this method
public static IPage GetInstance(Type type)
{
MethodInfo method = typeof(PageService).GetMethod("Create");
IPage page = (IPage)method.MakeGenericMethod(type).Invoke(null, new object[] { null });
return page;
}
Upvotes: 0
Views: 136
Reputation: 13233
Create a IBindingGenerator
:
public class MyBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(
Type type,
IBindingRoot bindingRoot)
{
yield return bindingRoot
.Bind(type)
.ToMethod(ctx => GetInstance(type));
}
public static object GetInstance(Type type)
{
MethodInfo method = typeof(PageService).GetMethod("Create");
return method.MakeGenericMethod(type).Invoke(null, new object[] { null });
}
}
and use it as follows:
kernel.Bind(x =>
{
x.FromThisAssembly()
.SelectAllClasses()
.WithAttribute<SomeAttribute>()
.BindWith<MyBindingGenerator>();
});
Upvotes: 0
Reputation: 99
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;
}
}
Upvotes: 0