Reputation: 847
We use Ninject for Dependency Injection. We are designing our code using our free-form-interpreted DDD, where a domain object is an IThing.
In the following code, how to get an IThingControl using an IThing instance?
interface IThing {}
class Thing : IThing {}
interface IThingControl<T> where T:IThing {}
class ThingControl<Thing> {}
class Module : NinjectModule {
public override void Load() {
Bind<IThingControl<Thing>>().To<ThingControl>();
}
}
class SomewhereInCode {
void AddControls() {
List<IThing> things = new List<IThing> {
new Thing()
};
foreach (IThing thing in things) {
IThingControl<IThing> control = _kernel.Get(); // <----- eh?
this.Controls.Add(control);
}
}
}
Upvotes: 1
Views: 1520
Reputation: 3464
I would revisit your design if you aim to retrieve a generic controller from an interface to its domain object.
Ninject does not play well with generic domain types as interfaces. This is due to the incovariance of generic types: Ninject - Managing Inconvariance of generic types?
Upvotes: 0
Reputation: 14580
You can get an instance using MakeGenericType
(here) but you can't cast it to IThingControl<IThing>
interface IThing { }
class Thing1 : IThing { }
class Thing2 : IThing { }
interface IThingControl<T> where T : IThing { }
class ThingControl<Thing> { }
class Module : NinjectModule {
public override void Load()
{
Bind(typeof(IThingControl<>)).To(typeof(ThingControl<>));
}
}
[TestFixture]
public class SomewhereInCode
{
[Test]
public void AddControls()
{
IKernel kernel = new StandardKernel(new Module());
List<IThing> things = new List<IThing> { new Thing1(), new Thing2() };
Type baseType = typeof(IThingControl<>);
foreach (IThing thing in things)
{
Type type = baseType.MakeGenericType(thing.GetType());
dynamic control = kernel.Get(type);
Assert.That(
control is IThingControl<IThing>,
Is.False);
}
}
}
Upvotes: 3