Intercept seule interface avec des méthodes DynamicProxy
-
22-09-2019 - |
Question
Je suis une interface comme ceci
public interface IService
{
void InterceptedMethod();
}
Une classe qui implémente cette interface et a également une autre méthode
public class Service : IService
{
public virtual void InterceptedMethod()
{
Console.WriteLine("InterceptedMethod");
}
public virtual void SomeMethod()
{
Console.WriteLine("SomeMethod");
}
}
Et un intercepteur
public class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Intercepting");
invocation.Proceed();
}
}
Je veux intercepter seulement les méthodes sur le service qui existe sur IService (i.e. Je veux intercepter InterceptedMethod () mais pas SomeMethod ()), mais je ne veux pas utiliser ShouldInterceptMethod de IProxyGenerationHook.
Je peux le faire comme ça, mais depuis son retour d'une interface, je ne peux pas appeler SomeMethod sur cet objet
var generator = new ProxyGenerator();
var proxy = generator.CreateInterfaceProxyWithTargetInterface<IService>(new Service(), new MyInterceptor());
proxy.InterceptedMethod(); // works
proxy.SomeMethod(); // Compile error, proxy is an IService
Une chose qui peut travailler est enlever le virtuel de SomeMethod () et faire comme ceci
var proxy = generator.CreateClassProxy<Service>(new MyInterceptor());
Mais je n'aime pas cette solution.
Je ne aime pas à l'aide de ShouldInterceptMethod IProxyGenerationHook, parce que chaque fois que je change l'interface, je dois aussi changer ShouldInterceptMethod, quelqu'un peut aussi un jour factoriser le nom de la méthode et la méthode n'interceptés plus.
Il y a une autre façon de le faire?
La solution
Si vous voulez créer un proxy pour la classe, vous devez utiliser classproxy.
Si vous voulez exclure certains membres, vous devez utiliser IProxyGenerationHook.
Si vous voulez que votre code soit agnostique aux changements aux membres de l'interface / classe comme les signatures nom ajoutés ou supprimés - que faire si
Code Simplest je pouvais penser est quelque chose comme ceci:
private InterfaceMap interfaceMethods = typeof(YourClass).GetInterfaceMap(typeof(YourInterface));
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return Array.IndexOf(interfaceMethods.ClassMethods,methodInfo)!=-1;
}