Intercept nur Methoden Schnittstelle mit Dynamic
-
22-09-2019 - |
Frage
Ich habe eine Schnittstelle wie diese
public interface IService
{
void InterceptedMethod();
}
A-Klasse, die implementiert diese Schnittstelle und auch eine andere Methode hat
public class Service : IService
{
public virtual void InterceptedMethod()
{
Console.WriteLine("InterceptedMethod");
}
public virtual void SomeMethod()
{
Console.WriteLine("SomeMethod");
}
}
Und ein Interceptor
public class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Intercepting");
invocation.Proceed();
}
}
Ich möchte nur die Methoden auf Service abfangen, die auf IService existiert (d Ich mag abfangen InterceptedMethod (), aber nicht Somemethod ()), aber ich will nicht ShouldInterceptMethod von IProxyGenerationHook verwenden.
Ich kann so tun, aber seit seiner Rückkehr einer Schnittstelle, kann ich nicht nennen Somemethod auf diesem Objekt
var generator = new ProxyGenerator();
var proxy = generator.CreateInterfaceProxyWithTargetInterface<IService>(new Service(), new MyInterceptor());
proxy.InterceptedMethod(); // works
proxy.SomeMethod(); // Compile error, proxy is an IService
Eine Sache, die arbeiten können, ist das Entfernen der virtuellen von Somemethod () und tun wie diese
var proxy = generator.CreateClassProxy<Service>(new MyInterceptor());
Aber ich weiß nicht, wie diese Lösung.
Ich habe wie ShouldInterceptMethod von IProxyGenerationHook verwenden, weil jedes Mal, dass ich die Schnittstelle ändern Ich muss auch ShouldInterceptMethod ändern, auch jemand eines Tages kann den Namen der Methode Refactoring und das Verfahren wird nicht mehr abgefangen werden.
Es gibt eine andere Möglichkeit, dies zu tun?
Lösung
Wenn Sie einen Proxy für die Klasse erstellen möchten, müssen Sie verwenden classproxy.
Wenn Sie bestimmte Mitglieder ausschließen wollen, müssen Sie IProxyGenerationHook verwenden.
Wenn Sie Ihr Code sein wollen Agnostiker, um Änderungen an Mitgliedern der Schnittstelle / Klasse wie Namen Signaturen hinzugefügt oder entfernt - als es so machen
Einfachstes Code, den ich von so etwas wie dies einfiel:
private InterfaceMap interfaceMethods = typeof(YourClass).GetInterfaceMap(typeof(YourInterface));
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return Array.IndexOf(interfaceMethods.ClassMethods,methodInfo)!=-1;
}