J'essaie de consigner les appels de l'interface utilisateur (module DNN) dans certains des différents services qu'il utilise, afin de déterminer comment les personnes interagissent avec le site. J'utilise StructureMap 2.5.3.0 et Log4NetEssayer de créer un Interceptor de journalisation pour StructureMap à l'aide de DynamicProxy
I GOT choses fonctionnent bien sur des paires classe/instance individuelle, mais je dois configurer des choses comme ceci:
ObjectFactory.Configure(ce =>
ce.ForRequestedType<IRegService>()
.TheDefaultIsConcreteType<RegService>()
.EnrichWith(LoggingEnrichment.InterfaceLogger<IRegService>));
Ayant le feutre deux fois IRegService
un peu en désordre mais je peux vivre avec.
L'exploitation forestière est mis en œuvre comme ceci:
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());
}
}
Cela fonctionne, mais il a un problèmes de couple:
- Je dois configurer manuellement chaque service < -> paire d'interface
- Je ne vous souhaitez câbler la journalisation lorsque le service est appelé à partir de l'interface utilisateur
J'ai essayé de contourner ce problème en mettant en œuvre un TypeInterceptor pour StructureMap:
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);
}
}
Mais je me pose un problème où l'appel à Process
me donne une classe qui ne met pas en oeuvre l'interface définie par la construire le contexte. Cela a donné lieu à devoir changer la mise en œuvre du InterfaceLogger
à
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;
}
Un point d'arrêt sur le return interfaceProxy;
est jamais atteint, cela signifie que context.BuildStack.Current.RequestedType
ne retourne pas l'interface droite. La chose étrange est que toutes mes classes semblent être injectées correctement.
De plus, même si cela fonctionnait, il me resterait toujours le problème de ne vouloir intercepter que les appels de la couche d'interface utilisateur.
Je suis à la recherche d'un moyen mes 2 premières questions, et aussi ce que je fais mal avec le TypeInterceptor
Bonjour, rencontré le même problème. Avez-vous résolu cela? Tnx. – daxsorbito
Salut, est-ce que ma réponse ci-dessous a résolu votre problème? Tnx. – daxsorbito