2016-04-29 12 views
1

一般的なインタフェースをデコレータでラップしようとしていますが、単に動作しません。これを行う唯一の方法は、デコレータごとに明示的に行うことです。私の質問は、特定のインタフェースを実装しているすべての型を特定のDecoratorとラップすることが可能かどうかです。ninjectを使用した一般的なデコレータパターン

コード:インターフェイスを実現するすべてのクラスでは、いくつかのメソッドの呼び出しを飾るために必要がある場合は

static void BindMediatr(IKernel kernel) { 
    kernel.Components.Add < IBindingResolver, ContravariantBindingResolver >(); 

    kernel.Bind(scan => scan.FromAssemblyContaining <IMediator>() 
    .SelectAllClasses() 
    .BindDefaultInterface()); 

    kernel.Bind <SingleInstanceFactory>().ToMethod(ctx => t => ctx.Kernel.Get(t)); 
    kernel.Bind <MultiInstanceFactory>().ToMethod(ctx => t => ctx.Kernel.GetAll(t)); 
    kernel.Bind(
    x => x.FromThisAssembly() 
    .SelectAllClasses() 
    .InheritedFromAny(typeof(IAsyncRequestHandler < , >)) 
    .BindAllInterfaces()); 

    kernel.Bind(typeof(IAsyncRequestHandler < , >)) 
    .To(typeof(Decorater < , >)) 
    .WhenInjectedInto <ApiController>(); 
} 

public class Decorater < TRequest, TResponse > 
    : IAsyncRequestHandler < TRequest, TResponse > 
    where TRequest: IAsyncRequest <TResponse> { 
    IAsyncRequestHandler < TRequest, 
    TResponse > _decoratee; 

    public Decorater(IAsyncRequestHandler < TRequest, TResponse > decoratee) { 
    _decoratee = decoratee; 
    } 

    public Task <TResponse> Handle(TRequest message) { 
    // do something here 
    } 
    } 

答えて

0

は、私は、トリックを行い、この拡張メソッドを見つけました?
0

、プロキシにすべてのバインディングを試すことができます。

Ninjectには、Interceptionと呼ばれる拡張機能があります。この拡張子を使用すると、特定の呼び出しを代行受信し、何らかのロジックでラップすることができます。

Hereはこれについての良い記事です。

希望、それは役に立ちます。

public static class KernelExtensions 
    { 
     /// <summary> 
     /// Binds an open generic type to its implementation and adds all its defined decorators 
     /// </summary> 
     /// <param name="kernel">Ninject Container</param> 
     /// <param name="openGenericType">Open generic Type</param> 
     /// <param name="assembly">Assembly to scan for the open generic type implementation</param> 
     /// <param name="decoratorTypes">Types of the decorators. Order matters. Order is from the most outer decorator to the inner decorator</param> 
     public static void BindManyOpenGenericsWithDecorators(this IKernel kernel, Type openGenericType, Assembly assembly, params Type[] decoratorTypes) 
     { 
      var allImplementations = GetAllTypesImplementingOpenGenericType(openGenericType, assembly); 

      foreach (var type in allImplementations.Where(type => !decoratorTypes.Contains(type))) 
      { 
       var genericInterface = type.GetInterfaces().FirstOrDefault(x => openGenericType.IsAssignableFrom(x.GetGenericTypeDefinition())); 

       // real implementation 
       var parentType = decoratorTypes.Last(); 
       kernel.Bind(genericInterface).To(type) 
       .WhenInjectedInto(parentType); 
      } 

      for (var i = 0; i <= decoratorTypes.Count() - 1; i++) 
      { 
       var decoratorType = decoratorTypes[i]; 

       if (i == 0) 
       { 
        // most outer decorator 
        kernel.Bind(openGenericType).To(decoratorType); 
       } 
       else 
       { 
        // inner decorators 
        var parentType = decoratorTypes[i - 1]; 
        kernel.Bind(openGenericType).To(decoratorType) 
         .WhenInjectedInto(parentType); 
       } 
      } 
     } 

     private static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly) 
     { 
      return (from type in assembly.GetTypes() 
        from interfaceType in type.GetInterfaces() 
        let baseType = type.BaseType 
        where 
        (baseType != null && baseType.IsGenericType && 
        openGenericType.IsAssignableFrom(baseType.GetGenericTypeDefinition())) || 
        (interfaceType.IsGenericType && 
        openGenericType.IsAssignableFrom(interfaceType.GetGenericTypeDefinition())) 
        select type); 
     } 
    } 
+0

私は傍受を提供していないよう一定のジェネリック型結果のかもしれません呼び出しアクションの結果を得ることができるようにする必要があります。 – Xerxes

関連する問題