UI(DNNモジュール)からの呼び出しを、さまざまなサービスのログに記録しようとしています。DynamicProxyを使用してStructureMapのログインターセプタを作成しようとしています
ObjectFactory.Configure(ce =>
ce.ForRequestedType<IRegService>()
.TheDefaultIsConcreteType<RegService>()
.EnrichWith(LoggingEnrichment.InterfaceLogger<IRegService>));
はIRegService
が二度少し厄介に感じ持って:私は、私は物事は、個々のクラス/インスタンスのペアにうまく機能してしまったが、私はこのようなものを設定する必要がありますのStructureMap 2.5.3.0とlog4netの
を使用していますしかし、私はそれで生きることができます。
ログは次のように実装されています
public class LoggingEnrichment
{
public static object InterfaceLogger<TInterface>(object concrete)
{
return InterfaceLogger(typeof(TInterface), concrete);
}
public static object InterfaceLogger(Type iinterface, object concrete)
{
var dynamicProxy = new ProxyGenerator();
return dynamicProxy.CreateInterfaceProxyWithTarget(iinterface, concrete, new LogInterceptor());
}
}
public class LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var watch = new Stopwatch();
watch.Start();
invocation.Proceed();
watch.Stop();
ILog logger = LogManager.GetLogger(typeof(LogInterceptor));
var sb = new StringBuilder();
sb.AppendFormat("Calling: {0}.{1}\n", invocation.InvocationTarget.GetType(), invocation.MethodInvocationTarget.Name);
var param = invocation.Method.GetParameters();
if (param.Length > 0) sb.Append("With:\n");
for (int i = 0; i < param.Length; i++)
{
sb.AppendFormat("\t{0}\n\t\t{1}", param[i].Name, invocation.GetArgumentValue(i));
}
if(invocation.Method.ReturnType != typeof(void))
{
sb.AppendFormat("Returning: {0}\n", invocation.ReturnValue ?? "null");
}
sb.AppendFormat("In: {0}ms\n", watch.ElapsedMilliseconds);
logger.Debug(sb.ToString());
}
}
これは動作しますが、夫婦の問題があります:私は手動で各サービス<設定する必要が
- - のみ>インターフェイスペア
- IをUIからサービスが呼び出されたときのログを取り消したい場合
私はのStructureMapのためTypeInterceptorを実装することによって、これを回避しようとした:
public class ApplicationRegistry : Registry
{
public ApplicationRegistry()
{
RegisterInterceptor(new LoggingInterceptor());
Scan(scanner =>
{
scanner.TheCallingAssembly();
var codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", String.Empty);
codeBase = codeBase.Substring(0, codeBase.LastIndexOf("/"));
scanner.AssembliesFromPath(codeBase);
scanner.WithDefaultConventions();
scanner.LookForRegistries();
});
}
}
public class LoggingInterceptor :TypeInterceptor
{
public object Process(object target, IContext context)
{
var newTarget = target;
if (context.BuildStack.Current != null && context.BuildStack.Current.RequestedType != null)
{
newTarget = LoggingEnrichment.InterfaceLogger(context.BuildStack.Current.RequestedType, target);
}
return newTarget;
}
public bool MatchesType(Type type)
{
return type.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase);
}
}
しかし、私はProcess
への呼び出しは私によって定義されたインタフェースを実装していないクラスを与えていることに問題があることを取得していますコンテキストを構築する。これはreturn interfaceProxy;
上のブレークポイントに到達されることはありません
public static object InterfaceLogger(Type iinterface, object concrete)
{
if(!iinterface.IsAssignableFrom(concrete.GetType())) return concrete;
var dynamicProxy = new ProxyGenerator();
var interfaceProxy = dynamicProxy.CreateInterfaceProxyWithTarget(iinterface, concrete, new LogInterceptor());
return interfaceProxy;
}
にInterfaceLogger
の実装を変更することになりました、これはcontext.BuildStack.Current.RequestedType
は、右のインターフェイスを返していないことを示します。奇妙なことは、すべてのクラスが正しく注入されているようです。
また、これが動作していても、UIレイヤーからの呼び出しを傍受したいという問題が残っています。
私は道のために私の最初の2つの問題を探しています、と私は条約を使って、これを周りましたTypeInterceptor
こんにちは、同じ問題に遭遇しました。これを解決しましたか? Tnx。 – daxsorbito
こんにちは、私の答えはあなたの問題を解決しましたか? Tnx。 – daxsorbito