L'injection de plusieurs implémentations avec l'injection de Dépendance
Je suis actuellement en train de travailler sur un ASP.NET Projet de Base et que vous voulez utiliser intégré dans l'Injection de Dépendance (DI) de la fonctionnalité.
Bien, j'ai commencé avec une interface:
ICar
{
string Drive();
}
et souhaitez mettre en œuvre la ICar
interface à plusieurs reprises comme
public class BMW : ICar
{
public string Drive(){...};
}
public class Jaguar : ICar
{
public string Drive(){...};
}
et ajoutez la ligne suivante dans le Startup
classe
public void ConfigureServices(IServiceCollection services)
{
//Add framework services.
services.AddMvc();
services.AddTransient<ICar, BMW>();
//or
services.AddTransient<ICar, Jaguar>();
}
Maintenant, je dois prendre une décision entre les deux implémentations et mes décidé de classe sera fixé dans chaque constructeur qui a besoin d'une ICar mise en œuvre. Mais mon idée était de dire, si la demande de Contrôleur est BMWController, puis utilisez BMW mise en œuvre ou l'utilisation de Jaguar si le JaguarController est demandé.
Autrement DI ne faites pas de sens pour moi. Comment puis-je traiter correctement ce problème?
Pour mieux comprendre mon problème, jetez un oeil à cette image: https://media-www-asp.azureedge.net/media/44907/dependency-injection-golf.png?raw=true
Comment la résolution de dépendances de travail et où puis-je le mettre en place ASP.NET Core?
Dans l'Unité, il est possible de faire quelque chose comme ceci
container.RegisterType<IPerson, Male>("Male");
container.RegisterType<IPerson, Female>("Female");
et appelez le type correct comme ça
[Dependency("Male")]IPerson malePerson
interface IBmwCar: ICar { ... }
et à l'injecter dans BMWController
. Autre idée est de créer de l'usine. f.e class CarFactory : ICarFactory { ICar GimmeCar<TController>() }
où vous avez mappé type de contrôleur à la mise en œuvre concrète.Merci pour la réponse.
N'est-il pas un débordement d'Interfaces si j'ai de l'utilisateur quelque chose comme IBmwCar : ICar pour toutes les marques je veux le mettre en œuvre? J'ai juste de la Voiture en tant que méthode, et n'aura pas d'autres. Eh bien, je voudrais créer puis IBMW, IJaguar... avec la même signature comme ICar et utiliser une instruction de ce genre pour chaque marque, j'ai mis en œuvre: services.AddTransient<IJaguar, Jaguar>(); Évidemment, je pourrais utiliser l'Usine de Motif, mais n'est-il pas une solution pour faire mon travail avec DI?
une chose à propos de la DI est que vous pouvez prendre une dépendance sur IEnumerable<ICar>, et obtenir toutes les réalisations qui ont été enregistrées, si aucune implémentations ont été enregistrés, vous obtenez une liste vide plutôt que l'échec à résoudre. Donc, si ICar a une certaine propriété d'identifiant vous pourrez trouver celui dont vous avez besoin dans la liste.
OriginalL'auteur DrScrum Milestone | 2016-12-03
Vous devez vous connecter pour publier un commentaire.
La fonctionnalité que vous recherchez n'est pas facile à mettre en œuvre, au moins lorsque vous l'utilisez dans le contrôleur parce que les contrôleurs sont traités un peu spécialement (Par défaut, les contrôleurs ne sont pas enregistrés avec
ServiceCollection
et n'est donc pas résolu/instancié par le conteneur et instanciées par ASP.NET de Base lors de la demande, voir aussi l'explication et exemple sur mes réponse).Avec construit-dans le conteneur IoC, vous ne pouvez le faire via la méthode de fabrique, ici avec un exemple sur un
BmwCarFactory
classe:La valeur par défaut conteneur IoC est intentionnellement simple de fournir des notions de base de l'injection de dépendance pour vous aider à démarrer et pour les autres conteneurs IoC pour être en mesure de facilement plugin-y, et remplacez la valeur par défaut de mise en œuvre.
Pour des scénarios plus avancés, les utilisateurs sont encouragés à utiliser un Cio de leur choix qui prend en charge davantage de fonctionnalités avancées (assemblée scan, décorateurs, conditionnel/paramétrée dépendances, etc.
AutoFac (que j'utilise dans mes projets) prend en charge de tels scénarios. Dans l'AutoFac documentation il y a 4 scénarios (tout à fait avec le 3e que @pwas suggéré dans les commentaires):
1. Refonte des classes
Besoins des surcharges supplémentaires de la refactorisation de votre code et de la hiérarchie de classe, mais simplifie fortement la consommation de injectés services
2. Modifier les enregistrements
Les documents décrivent il ici, si vous ne sont pas disposés ou pas en mesure de modifier le code.
3. À l'aide assortie de services (ici)
Il est assez similaire à l'approche précédente à 2. mais résout les services basés sur une touche, plutôt que de leur type de béton
4. Utiliser Les Métadonnées
C'est tout à fait similaire à 3. mais vous définissez via les touches de l'attribut.
Autres contenants comme L'unité ont des attributs spéciaux, comme
DependencyAttribute
que vous pouvez utiliser pour annoter la dépendance, commeMais ce et la 4e option de Autofac faire le conteneur IoC fuite dans vos services, et vous devriez envisager d'autres approches.
Alternativement, vous pouvez créer des classes et des usines qui résoudre vos services basés sur des conventions. Par exemple, un
ICarFactory
:Puis l'utiliser comme
Alternative à IServiceProvider
IEnumerable<ICar>
pour éviter la dépendance sur le conteneurC'est exactement ce que je cherchais, merci! J'ai utilisé de l'Unité avant dans mes Projets et je me demandais si il y a une possibilité de le faire dans originaires de DI ASP.NET de Base. J'ai eu la réponse merci!
j'ai juste un de plus question à, Point 1, pour une meilleure compréhension. Si une Interface d'avoir un seul de la mise en œuvre?
Dépend. Il peut a de multiples implémentations, mais vous choisissez un seul lors de l'inscription. Exemple peut être
IUserRepository
avoirSqliteUserRepository
etSqlServerUserRepositrory
et vous enregistrer qu'un seul. Si vous vous inscrivez à plusieurs reprises, vous ne pouvez pas facilement injecter en fonction du contexte ou de résoudre tous les d'eux avecIEnumerable<T>
. Donc, si vous voulez passerIBmwCar
w/o utiliser les autres options, alors oui, il ne devrait avoir qu'une mise en œuvreRemerciements 🙂
OriginalL'auteur Tseng