Comment accéder à Ninject.Kernel sans utiliser le modèle Service Locator
J'ai lu des dizaines de messages de ce sujet, sans trouver une ligne directrice claire de la façon d'accéder à la Ninject.Noyau sans l'aide du Localisateur de Service modèle.
Actuellement j'ai de la suite dans les classes qui ont besoin d'utiliser CustomerBusiness
(ce qui est mon service) et il fonctionne très bien, mais je suis bien conscient qu'il n'est pas recommandé de le faire.
private CustomerBusiness _customerBusiness;
private ICustomerRepository CustomerRepository
{
get { return NinjectWebCommon.Kernel.Get<IAccountRepository>(); }
}
private CustomerBusiness CustomerBusiness
{
get
{
if (_customerBusiness == null)
{
_customerBusiness = new CustomerBusiness(AccountRepository);
}
return _customerBusiness;
}
}
public Customer GetCustomer(int id)
{
return CustomerBusiness.GetCustomer(id);
}
C'est le Noyau de la propriété accessible dans le code ci-dessus:
public static IKernel Kernel
{
get
{
return CreateKernel();
}
}
J'ai lu de nombreuses suggestions sur l'utilisation d'une usine, mais aucun d'entre eux expliquent comment utilisation de cette usine. J'apprécierais vraiment si quelqu'un pouvait me montrer la "CustomerFactory" ou toute autre approche recommandée y compris comment utilisation.
Mise à jour
Je suis en utilisant ASP.NET des Formulaires Web et vous devez avoir accès CustomerBusiness
de Code-behind.
Solution
La dernière solution que j'ai trouvé de travail, a été la réponse avec le plus de votes trouvé à ce post:
Comment puis-je mettre en œuvre Ninject ou DI sur asp.net Formulaires Web?
Il ressemble à ceci (Notez l'héritage de PageBase, qui fait partie de Ninject.Le Web, c'est la clé!):
public partial class Edit : PageBase
{
[Inject]
public ICustomerBusiness CustomerBusiness { get; set; }
...
Accepté la réponse ci-dessous, indirectement, conduis-moi à trouver cette solution.
source d'informationauteur Niels Brinch
Vous devez vous connecter pour publier un commentaire.
Depuis que vous utilisez
NinjectWebCommon
je suppose que vous avez une application web de quelque sorte. Vous devriez vraiment avoir accès uniquement au noyau Ninject en un seul endroit - à l' la composition de la racine. C'est l'endroit où vous êtes la construction de l'objet graphique et le seul endroit où vous avez besoin d'un accès au conteneur IoC. En fait pour obtenir les dépendances dont vous avez besoin, vous emploient généralement constructeur injection.Dans le cas de la MVC applications web, par exemple, vous avez un contrôleur d'usine en utilisant le noyau Ninject et c'est le seul endroit où les références.
À développer votre situation particulière, de votre classe accepterait
ICustomerBusiness
dans son constructeur, en déclarant qu'il a besoin d'une instance deICustomerBusiness
que sa dépendance:Maintenant, selon la classe utilise
ICustomerBusinessConsumer
que sa dépendance, suit le même modèle (à l'acceptation d'une instance deICustomerBusinessConsumer
comme paramètre dans le constructeur). En gros, vous jamais de construire les dépendances à la main à l'aide denew
spécifique (sauf exceptions).Ensuite, vous avez juste à vous assurer que vos classes d'obtenir leurs dépendances et c'est cette composition de la racine où vous faites cela. Quelle est exactement la composition de la racine dépend du type d'application que vous écrivez (application console, application WPF, service web, application web MVC...)
MODIFIER: Pour me familiariser avec la situation de la ASP.NET WebForms domaine
J'ai eu à regarder les détails car je n'ai jamais utilisé. Malheureusement, WebForms vous obliger à avoir un constructeur sans paramètre à chacune de vos Page de catégories, de sorte que vous ne pouvez pas utiliser le constructeur de l'injection de tout le chemin à partir du haut de l'objet graphique vers le bas.
Toutefois, après consultation Marque Seeman'chapitre sur la composition des objets dans les Formulaires web, je peux reformuler la façon de traiter avec ce cadre de l'inefficacité, tout en agissant toujours en ligne avec une bonne DI pratiques:
Ont une classe chargée de résoudre les dépendances, à l'aide de la Ninject du noyau que vous avez configuré. Cela peut être une très mince wrapper autour du noyau. Appelons ça de la
DependencyContainer
.Créer votre conteneur et l'enregistrer dans le contexte de l'application, de sorte qu'il est prêt lorsque vous en avez besoin
Supposons que votre page de classe (appelons
HomePage
) a une dépendance surICustomerBusinessConsumer
. PuisDependencyContainer
a pour nous permettre de récupérer une instance deICustomerBusinessConsumer
:Que dans le
MainPage
classe elle-même, vous permettra de résoudre ses dépendances dans le constructeur par défaut:Quelques remarques:
avoir la dépendance de conteneurs disponibles dans la
HttpContext
ne doit pas être tentant de considérer un service locator. En fait, la meilleure pratique ici (au moins du point de vue de la véracité DI) est d'avoir une sorte de "réalisateur de" classes dont vous serez le relais de la fonctionnalité de votre page de classes.Par exemple, chaque action gérée par
MainPage
sera seulement relayé à son réalisateur de classe. Ce réalisateur de classe sera une dépendance deMainPage
et, comme toutes les autres dépendances, seront résolus à l'aide du conteneur.L'important, c'est que ces chargé de l'implémentation des classes devrait être dans les assemblages ne référence pas l'ASP.NET assemblées et donc sans possibilité d'accéder à la
HttpContext
avoir à écrire beaucoup de code pour obtenir ce n'est certainement pas idéal, mais c'est seulement une conséquence de la cadre de la prescription. Dans ASP.NET les applications MVC, par exemple, cette question est traitée dans une bien meilleure façon. Là, vous avez seul point où vous pouvez composer les graphes d'objets et que vous n'avez pas à les résoudre dans chaque niveau de classe que vous avez à WebForms.
la bonne chose est que si vous avez à écrire du code de plomberie dans la page de constructeurs de classe, à partir de là, l'objet graphique, vous pouvez utiliser le constructeur injection
Constructeur d'injection est la méthode préférée pour DI avec ninject, toutefois il prend également en charge la propriété de l'injection. Prendre une lecture de la ninject page autour de l'injection de patrons ici https://github.com/ninject/ninject/wiki/Injection-Patterns.
Ces deux sont des modèles injection à la différence de l'emplacement du service qui est à la base, pas vraiment d'injection.
Le revers de la médaille de l'injection, c'est que vous avez besoin pour contrôler la construction. Lors de l'utilisation de MVC tout le câblage pour ce faire est intégré dans le MVC ninject paquet sur nuget