以下が可能かどうか、また可能であればどうすればよいか疑問に思っています。以下のコードで説明してみます。
public class RandomClass
{
...
//class is filled with stuff of none importance for this demonstration
...
[LogScope("Start", "End")] //The important LogScope attribute!
public virtual void MyMethod()
{
...
//Doing something here but not the point now...
...
}
...
}
public LogScopeAttribute : InterceptAttribute
{
private readonly string _header;
private readonly string _footer;
public LogScopeAttribute(string header, string footer)
{
_header = header;
_footer = footer;
// This is just one of many constructors....
}
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Context.Kernel.Get<LogScopeInterceptor>(
new ConstructorArgument("header", _header),
new ConstructorArgument("footer", _footer));
// In the real version of this method there is more logic here for creating
// the right version of the interceptor, in regards to what constrcutor the
// LogScopeAttribute was called with.
}
}
public class LogScopeInterceptor : SimpleInterceptor
{
// No need to explain stuff here, (not of importance to the question)
// but what the interceptor does for me is write to log
// a header and footer and indent everything inside the logscope.
}
私が欲しいのは、メソッド内でカーネルを呼び出す必要がないように、Ninject を使用してILogScopeInterceptorFactory
aを挿入し、オブジェクトを挿入することです。このようにしたい...LogScopeAttribute
CreateInterceptor
ConstructorArgument
public LogScopeAttribute : InterceptAttribute
{
private readonly string _header;
private readonly string _footer;
private readonly ILogScopeInterceptorFactory _logScopeInterceptorFactory;
public LogScopeAttribute(ILogScopeInterceptorFactory logScopeInterceptorFactory ,string header, string footer)
{
_header = header;
_footer = footer;
_logScopeInterceptorFactory = logScopeInterceptorFactory;
}
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return _logScopeInterceptorFactory.Create(_header, _footer);
}
}
これは、次の
ようILogScopeInterceptorFactory
にバインドするインターフェイスです。Ninject.extensions.Factory
Bind<ILogScopeInterceptorFactory>().ToFactory();
public interface ILogScopeInterceptorFactory
{
LogScopeInterceptor Create(char separatorChar, string header, string footer);
LogScopeInterceptor Create(char separatorChar, string header);
LogScopeInterceptor Create(string header, string footer);
LogScopeInterceptor Create(string header);
LogScopeInterceptor Create(char separatorChar);
LogScopeInterceptor Create();
}
今私がやりたいことは、ファクトリを手動で挿入することなく、単に注入するだけで、LogScopeAttribute
このようなもの
を使用することです。どうすればそれを行うことができますか?[LogScope("Start", "End")]
EDIT2:
私は log4net を使用してログを記録しています。ここでLogScopeAttribute
は、何が行われているか、出力がどのように見えるかを書きます。
[LogScope("The Start", "The End")]
public virtual void MyMethod()
{
logger.Info("Hello World!");
}
OUTPUT:
logger: The Start
logger: Hello World!
logger: The End
ninject がすべてのメソッドをインターセプトするには、それらが and である必要がpublic
ありvirtual
ます。これはロギングに非常に便利で、メソッド内に記録されたすべてのものを簡単にインデントできます。ヘッダーとフッターが必要な場合、またはメソッドの実行時間をすべてそこに出力します。これはネストすることもできます...
@フェリックス
問題は、カーネルを取得できないことではありません...カーネルを呼び出してファクトリを作成したい場合は、次のようにすることができます。
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
var factory = request.Context.Kernel.Get<ILogScopeInterceptorFactory>();
return factory.Create(_header, _footer);
}
ファクトリを手動で挿入した場合、すべての属性に対してこれを行う必要があります
[LogScope(_logScopeInterceptorFactory, "header", "footer")]
そして、それはただの醜いものです