Je crée un ActionResult
personnalisé pour mes contrôleurs car j'ai remarqué que beaucoup de code répété pouvait être réutilisé. Il ressemble à ceci:Injection de dépendances lors de la construction de l'objet
public ExtendedViewResult<T> : ActionResult
{
protected T Model { get; set; }
protected IModelExtender<T> Extender { get; set; }
public ExtendedActionResult(T model, IModelExtender<T> extender)
{
this.Model = model;
this.Extender = extender;
}
}
public class BaseController : Controller
{
public ExtendedViewResult<T> ExtendedView<T>(T model)
{
// I need to create the result here, but how?
var result = new ExtendedViewResult<T>(model, ???????);
return result;
}
}
Le problème que j'ai est que je ne suis pas sûr de savoir comment construire mon objet ExtendedViewResult. Comme l'interface est générique, je veux utiliser Dependency Injection pour obtenir l'objet approprié, mais je ne suis pas sûr de savoir comment le faire puisque je construis l'objet moi-même.
J'utilise Ninject et Ninject.MVC3 et la valeur par défaut package Nuget crée une classe Bootstrapper pour moi, et quand j'accéder à la propriété Bootstrapper.Kernel je reçois l'avertissement suivant:
Ninject.Web.Mvc.Bootstrapper.Kernel is obsolete. Do not use Ninject as Service Locator.
Si je Je ne suis pas supposé accéder au noyau directement, alors comment puis-je changer mon code pour pouvoir obtenir la classe concrète appropriée?
EDIT
Voici le code ninject bootstrapper. La seule méthode que j'ai ajoutée est le GetInstance()
public static class NinjectMVC3
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
// I ADDED THIS CODE, EVERYTHING ELSE IS AUTO-GENERATED
// BY THE NUGET PACKAGE
public static T GetInstance<T>()
{
return bootstrapper.Kernel.Get<T>();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
}
}
Le problème avec le passage dans le contrôleur concret est que je pourrais avoir 10 différentes méthodes d'action qui ont tous des modèles différents. Pour ce faire, je devrais passer 10 dépendances Func différentes à mon contrôleur, ce qui ne semble pas être la meilleure option. – Dismissile
@Dississile Dans ce cas, je recommanderais de créer vous-même une usine. Je ne pense pas que ninject puisse créer automatiquement des usines basées sur un générique ouvert, et le paramètre constructeur le rend plus difficile.Si vous trouvez que c'est possible, veuillez mettre à jour votre question, éditer cette réponse ou répondre à votre propre question - J'aimerais voir le résultat. Mon conteneur de choix est AutoFac, et je pense qu'il faudrait un peu de magie de registrationsource pour y parvenir. –
@Dississile concernant votre propre usine, n'oubliez pas que vous pouvez prendre une dépendance sur IResolutionRoot et appeler .Get sur cela. Dans le cas simple, vous pourriez simplement prendre une dépendance sur IResolutionRoot dans votre BaseController. Ceci utilise à peu près un ServiceLocator, mais vous demandez le locator en tant que dépendance plutôt que de le trouver vous-même. –