Come si crea un provider Ninject quando il costruttore di tipo non è noto?
-
07-07-2019 - |
Domanda
Ho deciso di provare a evocare un assieme contenitore con cui interagire FubuMVC. Bene la parte interessante è che ha superato tutti i test che il FubuMVC.Container.StructureMap lo fa. Tuttavia, quando ho lasciato cadere nel FubuSample. Ho ricevuto un errore di attivazione.
L'errore è perché nel provider sono solo i comportamenti chiamando un costruttore senza parametri per creare istanze di comportamento. Quello sembra inaccettabile nella vita reale.
Ecco come è impostato:
public class TestBehavior2 : IControllerActionBehavior
{
public IControllerActionBehavior InsideBehavior { get; set; }
public IInvocationResult Result { get; set; }
protected FubuConfiguration Configuration { get; set; }
protected FubuConventions Conventions { get; set; }
public TestBehavior2(FubuConventions conventions, FubuConfiguration config)
{
Conventions = conventions;
Configuration = config;
}
public OUTPUT Invoke<INPUT, OUTPUT>(INPUT input, Func<INPUT, OUTPUT> func)
where INPUT : class
where OUTPUT : class
{
// Invocation stuff
}
}
public class TestBehavior : IControllerActionBehavior
{
public IControllerActionBehavior InsideBehavior { get; set; }
public IInvocationResult Result { get; set; }
public OUTPUT Invoke<INPUT, OUTPUT>(INPUT input, Func<INPUT, OUTPUT> func)
where INPUT : class
where OUTPUT : class
{
// Invocation stuff
}
}
Il metodo My Load contiene questi binding:
foreach (var actionConfig in _configuration.GetControllerActionConfigs())
{
Bind(actionConfig.ControllerType).ToSelf();
Bind<IControllerActionBehavior>()
.ToProvider(new BehaviorInstanceProvider(actionConfig))
.WhenParentNamed(actionConfig.UniqueID);
Bind<IControllerActionInvoker>().To(actionConfig.InvokerType)
.Named(actionConfig.UniqueID);
}
Nel metodo di creazione del mio provider è:
public object Create(IContext context)
{
var behavior = ConfigureInstance(context);
foreach (var type in _config.GetBehaviors().Reverse())
{
IControllerActionBehavior previousBehavior = behavior;
behavior = (IControllerActionBehavior)Activator.CreateInstance(type);
t.GetProperty(INSIDE_PROP_NAME).SetValue(behavior, temp, null);
}
return behavior;
}
Quindi la mia domanda è come devo impostare il provider per creare un istanza di un servizio quando tutto non so cosa farà il costruttore Assomiglia a? O meglio se uso ConstructorInfo per accertare il il costruttore Ninject inietterà le dipendenze appropriate?
Questo utilizza Ninject 2b, poiché FubuMvc richiede CommonServiceLocator supporto.
Soluzione
Non importa, ho scoperto che stavo rendendo le cose più complicate di quanto dovesse essere. Ecco il mio nuovo metodo di creazione:
public object Create(IContext context)
{
IControllerActionBehavior behavior = context.Kernel.Get<DefaultBehavior>();
_config.GetBehaviors().Reverse().Each(t =>
{
var temp = behavior;
behavior = (IControllerActionBehavior) context.Kernel.Get(t);
t.GetProperty(INSIDE_PROP_NAME).SetValue(behavior, temp, null);
});
_type = behavior.GetType();
return behavior;
}
Tutto quello che dovevo fare era solo prendere i tipi di comportamento concreti e tutti erano felici.