2

Ninjectは、Ninjectが無視するようにクラスまたはコンストラクタを修飾するために使用できる属性を持っていますか?Ninjectが暗黙のバインディングリストから型を隠すように指示する方法

私は取り除く必要があります。

循環的な依存関係は2つの サービスのコンストラクタとの間で検出されました。

これは私のコードです:あなたはBindContextual Bindingを使用することができるはず

kernel.Bind(typeof(ICommandHandler<>)) 
    .To(typeof(TransactionCommandHandlerDecora‌​tor<>)); 
+1

同じ効果を達成するためにWith.Interceptionを使用できますが、デコレータのルートは非常に有効な方法です。 –

+0

Ninject Wiki全体を読んだことがあり、コンストラクタを無視する方法が見つかりません。と。最適なソリューションではありませんが、すべてのコントローラコンストラクターに配置する必要があります。問題を引き起こすコンストラクターにIgnoreを配置する方が合理的です。 – Tomas

答えて

1

// Abstraction 
public interface ICommandHandler<TCommand> 
{ 
    void Handle(TCommand command); 
} 

// Implementation 
public class ShipOrderCommandHandler 
    : ICommandHandler<ShipOrderCommand> 
{ 
    private readonly IRepository<Order> repository; 

    public ShipOrderCommandHandler(
     IRepository<Order> repository) 
    { 
     this.repository = repository; 
    } 

    public void Handle(ShipOrderCommand command) 
    { 
     // do some useful stuf with the command and repository. 
    } 
} 

私の一般的なデコレータ:

public TransactionalCommandHandlerDecorator<TCommand> 
    : ICommandHandler<TCommand> 
{ 
    private ICommandHandler<TCommand> decoratedHandler; 

    public TransactionalCommandHandlerDecorator(
     ICommandHandler<TCommand> decoratedHandler) 
    { 
     this.decoratedHandler = decoratedHandler; 
    } 

    public void Handle(TCommand command) 
    { 
     using (var scope = new TransactionScope()) 
     { 
      this.decoratedHandler.Handle(command); 
      scope.Complete(); 
     } 
    } 
} 

私のコンテナの登録constを持つ生のインタフェースそれらが適切なコンテキストでのみ考慮されるようにする(つまり、デコレータに入るとき)。

私は非常によく似たWhenエクステンションを持っています。あなたがまだそれを見ているなら、明日ここに貼り付けることができます。

編集:私は念頭に置いていたコード(それはあなたが直接欲しい欲しいんdoes notの判明)デコレータを接続するために使用

public static class NinjectWhenExtensions 
{ 
    public static void WhenRootRequestIsFor<T>(this IBindingSyntax that) 
    { 
     that.BindingConfiguration.Condition = request => request.RootRequestIsFor<T>(); 
    } 
} 

public static class NinjectRequestExtensions 
{ 
    public static bool RootRequestIsFor<T>(this IRequest request) 
    { 
#if false 
     // Need to use ContextPreservingGet in factories and nested requests for this to work. 
     // http://www.planetgeek.ch/2010/12/08/ninject-extension-contextpreservation-explained/ 
     return RootRequest(request).Service == typeof(T); 
#else 
     // Hack - check the template arg is the interface wer'e looking for rather than doing what the name of the method would actually suggest 
     IRequest rootRequest = RootRequest(request); 
     return rootRequest.Service.IsGenericType && rootRequest.Service.GetGenericArguments().Single() == typeof(T); 
#endif 
    } 

    static IRequest RootRequest(IRequest request) 
    { 
     if (request.ParentRequest == null) 
      return request; 

     return RootRequest(request.ParentRequest); 
    } 
} 

: -

root.Bind<IEndpointSettings>().To<IAnonymousEndpointSettings>().WhenRootRequestIsFor<IAnonymousService>(); 
root.Bind<IEndpointSettings>().To<IAuthenticatedSettings>().WhenRootRequestIsFor<IServiceA>(); 

EDIT 2:あなたはできるはずですResolve dがデコレータに供給されている場合を除いて、IXの一般バインディングを画像の外に取り出すWhen派生を作成するために使用します。次に、デコレータのBindはコンテキスト保存(@Remoに記事があります)を使用してコンテキストに入るようにして、述語が決定できるようにするか、メタデータをリクエストに追加して、 。

だから、私がしたい:あなたのWhen状態に入ってくると、あなたが適切にフィルタリングすることができます方法を決定する要求にコンテキストの内容をダンプ/調べる2. コンテキスト保全に関する 1.読み取りを。

(そして誰かが缶詰1つのライナーの答えと一緒に来ることを願っています!)

コンテキスト保存拡張子が再生する部分を有していてもよいです。

+0

はい、コードを投稿してください。ありがとうございました! – Tomas

+0

@Tomasが更新されました。後でもっと来ること。 –

+0

@Tomasが再び更新されました。申し訳ありませんが、テストでは完全な作業コードではありません - それを行うには、現時点では時間がありませんでした、楽しいとすべてそれを解決するだろう! –

2

コードに基づいた実例があります。ベストNinject.Extensions.Conventionsで使用

public class AutoDecorationFacts 
{ 
    readonly StandardKernel _kernel = new StandardKernel(); 

    public AutoDecorationFacts() 
    { 
     _kernel.Bind(typeof(ICommandHandler<>)) 
      .To(typeof(TransactionalCommandHandlerDecorator<>)) 
      .Named("decorated"); 
    } 

    [Fact] 
    public void RawBind() 
    { 
     _kernel.Bind(typeof(ICommandHandler<>)).To<ShipOrderCommandHandler>().WhenAnyAnchestorNamed("decorated"); 
     VerifyBoundRight(); 
    } 

    void VerifyBoundRight() 
    { 
     var cmd = _kernel.Get<ICommandHandler<ShipOrderCommand>>(); 
     Assert.IsType<TransactionalCommandHandlerDecorator<ShipOrderCommand>>(cmd); 
    } 

: -

[Fact] 
    public void NameSpaceBasedConvention() 
    { 
     _kernel.Bind(scan => scan 
      .FromThisAssembly() 
      .SelectAllClasses() 
      .InNamespaceOf<CommandHandlers.ShipOrderCommandHandler>() 
      .BindAllInterfaces() 
      .Configure(x => x.WhenAnyAnchestorNamed("decorated"))); 
     VerifyBoundRight(); 
    } 

    [Fact] 
    public void UnconstrainedWorksTooButDontDoThat() 
    { 
     _kernel.Bind(scan => scan 
      .FromThisAssembly() 
      .SelectAllClasses() 
      .BindAllInterfaces() 
      .Configure(x=>x.WhenAnyAnchestorNamed("decorated"))); 
     VerifyBoundRight(); 
    } 
} 

あなたのクラス:

publicクラスはNinjectの { }

// Abstraction 
public interface ICommandHandler<TCommand> 
{ 
    void Handle(TCommand command); 
} 

// Implementation 
namespace CommandHandlers 
{ 
    public class ShipOrderCommandHandler 
     : ICommandHandler<ShipOrderCommand> 
    { 
     public ShipOrderCommandHandler(
      ) 
     { 
     } 

     public void Handle(ShipOrderCommand command) 
     { 
      // do some useful stuf with the command and repository. 
     } 
    } 
} 
public class TransactionalCommandHandlerDecorator<TCommand> 
    : ICommandHandler<TCommand> 
{ 
    private ICommandHandler<TCommand> decoratedHandler; 

    public TransactionalCommandHandlerDecorator(
     ICommandHandler<TCommand> decoratedHandler) 
    { 
     this.decoratedHandler = decoratedHandler; 
    } 

    public void Handle(TCommand command) 
    { 
     this.decoratedHandler.Handle(command); 
    } 
} 

(使用NuGet-最新バージョンをShipOrderCommandし、 Ninject.Extensions.Conventions)

+0

トランザクションデコレータ(ExecutionTimeCommandHandlerDecorator)の上に別のデコレータを追加するにはどうすればよいですか? –

+0

@Discofunk https://github.com/ninject/ninject/wiki/Contextual-Bindingを参照してください。一般に、「WhenInjectedInto」と友人を使用します(上の '.Named'トリックは、あなたが構成的ではなく、正直であることを指摘しています)それを見て、誰がそれを書いたのだろうか) –

関連する問題