2010-07-12 13 views
9

Existe-t-il un moyen d'utiliser Injection de propriété dans Ninject 2 sans utiliser l'attribut [Inject]? Cela crée une dépendance à Ninject dans la classe qui sera câblée en l'utilisant et je préfère éviter les dépendances inutiles à mon conteneur IoC, c'est pourquoi je finis par utiliser Constructor Injection plus souvent.Ninject 2.0: Injection de propriété sans attribut

Je suppose que la même méthode pour injection

Répondre

7

Je suivais la pointe de Ruben et posté une petite blog post sur la façon d'y parvenir, mais voici la réponse rapide:

Créer un attribut personnalisé:

public class InjectHereAttribute : Attribute 
{ 
} 

la classe cible ressemblera à ceci:

Maintenant Ninject doit être configuré pour utiliser l'attribut personnalisé, cela peut être fait en créant une mise en œuvre de IInjectionHeuristic qui reconnaît l'attribut personnalisé:

public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable 
{ 
    public new bool ShouldInject(MemberInfo member) 
    { 
     return member.IsDefined(
      typeof(InjectHereAttribute), 
      true); 
    } 
} 

Et enfin ajouter ce comportement au noyau Ninject à l'aide la collection Components, elle fonctionnera le long des composants existants, à savoir l'implémentation par défaut de IInjectionHeuristic, ce qui signifie que l'attribut par défaut ou personnalisé peut être utilisé.

// Add custom inject heuristic 
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>(); 
+0

Le lien n'existe plus (illustrant ainsi pourquoi il est toujours préférable de copier/coller et donner crédit à l'auteur original, plutôt que de simplement lier l'original). Avez-vous une ressource alternative pour décrire la réponse originale à ce problème? – BTownTKD

+0

@BTownTKD vous avez raison. J'ai ajouté l'exemple à la réponse et changé le lien cassé. – t3mujin

+0

Merci! Cela semble très utile. – BTownTKD

4

Vous pouvez passer dans un autre [attribut] type au noyau lors de la création qui peut être utilisé au lieu de InjectAttribute, mais vous aurez encore à référencer quelque chose au centre OOTB. Il y avait une question similaire très récemment à propos de PI sans attributs - il n'y a pas OOTB (comme dans directement sur l'interface de configuration fluide) pour mettre dans un scanner personnalisé mais les points d'extensibilité (vous ajoutez un composant qui implémente une interface Ninject comme vous construisez votre noyau qui dicte comment cet aspect doit être travaillé si vous recherchez un attribut donné n'est pas ce que vous voulez) sont là pour déterminer où injecter basé sur Convention sur Configuration - il n'y a rien qui vous empêche de modifier l'analyse pour être basé sur juste un nom d'attribut (donc il ne doit pas nécessairement vivre dans un emplacement central).

Notez que, en général, l'injection de constructeur est bon pour beaucoup de raisons de toute façon, y compris celui-ci, et vous contenant de code garder agnostique est importante (même si vous êtes actuellement satisfait de l'un!)

3

j'ai pu y arriver en utilisant une classe Heuristique:

public sealed class MyInjectionHeuristic : NinjectComponent, IInjectionHeuristic 
{ 
     private static readonly IList<Type> 
      _propertyInjectible = 
       new List<Type> 
       { 
      typeof(IMyService), 
       }; 

        /// <summary> 
     /// Returns a value indicating whether the specified member should be injected. 
     /// </summary> 
     /// <param name="member">The member in question.</param> 
     /// <returns><c>True</c> if the member should be injected; otherwise <c>false</c>.</returns> 
     public bool ShouldInject(MemberInfo member) 
     { 
     var info = member as PropertyInfo; 

     if(member == null || info == null) 
     return false; 

     if (info.CanWrite) 
     return _propertyInjectible.Contains(info.PropertyType); 

     if(this.Settings == null) 
     return false; 

     var propList = member.GetCustomAttributes(this.Settings.InjectAttribute, true); 

     return propList.Length > 0; 
     } 
} 

Lorsque vous créez votre noyau:

var heuristics = _kernel.Components.Get<ISelector>().InjectionHeuristics; 
    heuristics.Add(new MyInjectionHeuristic()); 

Simple ajouter des types supplémentaires à IList lorsque vous voulez injecter d'autres types via les propriétés.