4

J'ai ce modèlemodèle de conception pour un contrôleur de base avec injection dependecy - MVC 3 + Ninject

public abstract class BaseController : Controller 
{ 
    readonly RepositoryFactory _rep; 
    protected RepositoryFactory rep 
    { 
     get 
     { 
      return _rep; 
     } 
    } 

    readonly ManageRoles _man; 

    readonly ElementAvailableForUser _env; 
    protected ElementAvailableForUser env 
    { 
     get 
     { 
      return _env; 
     } 
    } 

    public BaseController() 
     : this(DependencyResolver.Current.GetService<RepositoryFactory>(), 
      DependencyResolver.Current.GetService<ManageRoles>(), 
      DependencyResolver.Current.GetService<ElementAvailableForUser>()) { } 

    public BaseController(RepositoryFactory rep, ManageRoles man, ElementAvailableForUser env) 
    { 
     _rep = rep; 
     _man = man; 
     _env = env; 
    } 
} 

Je suis donc en mesure de faire quelque chose comme ça

public class HomeController : BaseController 
{ 
    public ActionResult Index() 
    { 
     return View(rep.Offers.GetAll()); 
    } 

    public ActionResult Sections() 
    { 
     return View(env); 
    } 
} 

dans tout mon contrôleur . Je suis sûr que ce soit pour DI et antimodèle IoC, donc je mince une solution comme celui-ci

public abstract class BaseController : Controller 
{ 
    ... 

    // removed empty constructor 

    public BaseController(RepositoryFactory rep, ManageRoles man, ElementAvailableForUser env) 
    { 
     _rep = rep; 
     _man = man; 
     _env = env; 
    } 
} 

public class HomeController : BaseController 
{ 
    public HomeController(RepositoryFactory rep, ManageRoles man, ElementAvailableForUser env) : base(rep, man, env) { } 

    ... 
} 

mais cette solution me oblige à insérer toutes les dépendances dans tous les contrôleurs et mettre à jour tout constructeur si je besoin d'une nouvelle variable globale (comme rep) ou une nouvelle variable privée pour basecontroller (comme man).

Quel schéma dois-je suivre et pourquoi?

Modifier J'ai trouvé ce question et this, mais je ne peux pas comprendre quels sont les modèles de conception dois-je suivre.

+1

Qu'est-ce qui vous fait penser à un modèle de conception que vous devriez suivre? – bzlm

+0

Cause seul un de ceci devrait être utilisé dans mon application. –

Répondre

0

Je ne pense pas avec la solution mince que vous devez toujours déclarer rep, man, et env. Vous pouvez tirer parti des paramètres par défaut/facultatifs.

public BaseController(RepositoryFactory rep = null, ManageRoles man = null, ElementAvailableForUser env = null) 
{ 
    _rep = rep; 
    _man = man; 
    _env = env; 
} 

Vous pouvez ensuite utiliser les affectations de paramètre nommé

public class HomeController : BaseController 
{ 
    public HomeController(ManageRoles man) : base(man: man) { } 

    ... 
} 
+0

Oui, mais dans ce cas l'IoC ne fonctionne pas et les résultats "man" sont toujours NULL s'ils n'ont pas été déclarés explicitement dans le contrôleur enfant. –

3

Il ne semble pas que vous avez besoin de l'BaseController dans ce cas. Je pense qu'il serait plus facile (et plus testable) de faire quelque chose comme ceci:

public class HomeController : Controller 
    { 
     private readonly IRepository<Offers> _repository; 
     private readonly RoleManager _roleManager; 
     private readonly UserManager _userManager; 

     public HomeController(IRepository<Offers> repository, RoleManager roleManager, UserManager userManager) 
     { 
      _repository = repository; 
      _roleManager = roleManager; 
      _userManager = userManager; 
     } 
    } 

Ensuite, vous pourriez avoir votre fil de conteneur IoC jusqu'à toutes les dépendances automatiquement pour chaque contrôleur.

+0

Oui, cela pourrait être le cas, mais j'ai besoin de remplir l'objet de la même manière pour tout le contrôleur, et je le fais dans la méthode actionexecuting du contrôleur de base. –

Questions connexes