比較的大きなコードベースを Ninject 2.2 から Ninject 3.0 にアップグレードしました。私たちが使用するインターセプトにいくつかの変更を加える必要があったことを除いて、すべてが計画どおりに進んでいるようです.
interface IFoo
{
Bar GetBar();
}
class Foo : IFoo
{
[LogMethod(Level = LogLevel.Error)]
public virtual Bar GetBar()
{
return new Bar();
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
class LogMethodAttribute : InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Kernel.Get<ILogMethodInterceptor>();
}
public LogLevel Level { get; set; }
}
interface ILogMethodInterceptor : IInterceptor { }
class LogMethodInterceptor : ILogMethodInterceptor
{
public void Intercept(IInvocation invocation)
{
LogMethodAttribute attr = (LogMethodAttribute)invocation.Request.Method.GetCustomAttributes(typeof(LogMethodAttribute), true).FirstOrDefault();
// Log something - using attribute properties
}
}
NinjectSettings settings = new NinjectSettings { LoadExtensions = false };
IKernel kernel = new StandardKernel(settings, new DynamicProxy2Module());
kernel.Bind<ILogMethodInterceptor>().To<LogMethodInterceptor>();
kernel.Bind<IFoo>().To<Foo>();
この縮小バージョンは、Ninject 2.3 で大きな効果を発揮するために使用したものです。インターフェイス プロキシが許可されていないため、すべてのメソッドを仮想としてマークし、Castle 動的プロキシがそれらをオーバーライドできるようにしました。
[LogMethod] をインターフェイス レベルに移動して、インターフェイス プロキシを使用します。
ただし、移動すると、Ninject はこのクラスを傍受したいことを検出しなくなります。また、そのままにしておくと、微妙な問題が発生します。
これinvocation.Request.Method
は Interface からの MethodInfo ですIFoo
。実装Foo
ではありません。これは、属性を取得できなくなったことを意味します。したがって、現時点ではこれら2つの問題の間で立ち往生しています-属性をインターフェースに配置すると、Ninjectはプロキシを作成しません.実装に属性を配置すると、属性を簡単に取得してそのプロパティにアクセスできません。現時点で私の唯一の解決策はこれです:
interface IFoo
{
[LogMethod(Level = LogLevel.Error)]
Bar GetBar();
}
class Foo : IFoo
{
[LogMethod(Level = LogLevel.Error)]
public virtual Bar GetBar()
{
return new Bar();
}
}
または、InterfaceMapping を使用して、私の IFooMethodInfo
をinvocation.Request.Target.GetType()
(実装タイプを返す - Foo
)に変換しますMethodInfo
。
推奨事項はありますか?