1

汎用インターフェイスをデコレータでラップしようとしていますが、単に機能しません。他の質問から、これを行う唯一の方法はデコレータごとに明示的に行うことだと思われます。私の質問はそれが可能かどうかです特定のインターフェイスを実装するすべてのタイプを ninject の特定の Decorator でラップします。

コード:

 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
   }
  }
4

2 に答える 2

0

インターフェイスを実現するすべてのクラスで何らかのメソッドの呼び出しを装飾する必要がある場合は、すべてのバインディングをプロキシすることができます。

Ninject には - Interceptionと呼ばれる拡張機能があり、メソッドへの特定の呼び出しをインターセプトし、いくつかのロジックでラップすることができます。

これについては良い記事があります

それが役に立てば幸い。

于 2016-04-29T15:22:06.017 に答える
0

トリックを行うこの拡張メソッドを見つけました:

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);
        }
    }
于 2016-04-29T16:51:09.660 に答える