2013-05-30 3 views
3

Nous utilisons des liaisons basées sur les conventions Ninjects pour lier automatiquement un ensemble de commandes et de requêtes à leurs gestionnaires. Jusqu'à présent, nous avons un décorateur travaillant en utilisant ce qui suit.Liaisons et décorateurs basés sur les conventions Ninject

Bind tout sans l'attribut:

Kernel.Bind(x => 
     x.FromThisAssembly() 
     .SelectAllClasses() 
     .InheritedFrom(typeof(ICommandHandler<>)) 
     .WithoutAttribute<DoCheckAttribute>() 
     .BindAllInterfaces()); 

Bind tout avec l'attribut:

Kernel.Bind(x => 
     x.FromThisAssembly() 
     .SelectAllClasses() 
     .InheritedFrom(typeof(ICommandHandler<>)) 
     .WithAttribute<DoCheckAttribute>() 
     .BindAllInterfaces() 
     .Configure(c => c.WhenInjectedInto(typeof(DoCheckDecorator<>)))); 

Nous avons essayé ce qui suit pour ajouter un autre décorateur, mais cela échoue.

Bind tout sans l'attribut:

Kernel.Bind(x => 
     x.FromThisAssembly() 
     .SelectAllClasses() 
     .InheritedFrom(typeof(ICommandHandler<>)) 
     .WithoutAttribute<DoCheckAttribute>() 
     .WithoutAttribute<DoOtherCheckAttribute>() 
     .BindAllInterfaces()); 

Bind tout avec l'attribut:

Kernel.Bind(x => 
     x.FromThisAssembly() 
     .SelectAllClasses() 
     .InheritedFrom(typeof(ICommandHandler<>)) 
     .WithAttribute<DoCheckAttribute>() 
     .WithoutAttribute<DoOtherCheckAttribute>() 
     .BindAllInterfaces() 
     .Configure(c => c.WhenInjectedInto(typeof(DoCheckDecorator<>)))); 

    Kernel.Bind(x => 
     x.FromThisAssembly() 
     .SelectAllClasses() 
     .InheritedFrom(typeof(ICommandHandler<>)) 
     .WithoutAttribute<DoCheckAttribute>() 
     .WithAttribute<DoOtherCheckAttribute>() 
     .BindAllInterfaces() 
     .Configure(c => c.WhenInjectedInto(typeof(DoOtherCheckDecorator<>)))); 

Est-il possible d'y parvenir en utilisant de cette manière Ninject? Devons-nous revenir à la définition manuelle de chaque liaison, c'est-à-dire?

Bind<X>.To<Y>.WhenInjectedInto(?) 

Idéalement, nous devrions utiliser la syntaxe comme:

Bind<X>.To<Y>.WithDecorator<Z>.When(a => a.HasAttribute<DoCheckAttribute>) 
+0

Êtes-vous accro à Ninject? Si vous le souhaitez, je peux vous montrer comment faire avec Simple Injector: avec des décorateurs. Avec Simple Injector, c'est plutôt facile. – Steven

Répondre

2

Il semble donc que Ninject a déjà une extension qui peut résoudre ce problème. En utilisant l'extension intercepteurs il est possible d'écrire un attribut comme:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 
    public sealed class DoCheckAttribute : InterceptAttribute 
    { 
     public override IInterceptor CreateInterceptor(IProxyRequest request) 
     { 
      return request.Context.Kernel.Get<DoCheckInterceptor>(); 
     } 
    } 

L'interception réelle est écrit alors:

public class DoCheckInterceptor : IInterceptor 
    { 
     public void Intercept(IInvocation invocation) 
     { 
      //Do Work 
      invocation.Proceed(); 
     } 
    } 

Cela signifie que les liaisons deviennent aussi simples que:

Kernel.Bind(x => 
     x.FromThisAssembly() 
     .SelectAllClasses() 
     .InheritedFrom(typeof(ICommandHandler<>)) 
     .BindAllInterfaces()); 

De nouveaux attributs peuvent maintenant être facilement ajoutés sans aucune modification des liaisons. Plusieurs attributs peuvent également avoir l'ordre dans lequel ils s'exécutent, tels que:

 [DoCheck(Order = 0), DoOtherCheck(Order = 1)] 
    public class TestClass 
    { 
    } 
Questions connexes