2013-08-21 13 views
6

dynamic proxy klasa to klasa, która implementuje listę interfejsów określonych w czasie wykonywania tak, że metoda A powoływanie się przez jeden z interfejsów instancji klasy będą kodowane i wysyłane do inny obiekt poprzez jednolity interfejs. Można go użyć do utworzenia obiektu proxy proxy dla listy interfejsów bez wymaganej wersji wymagającej wstępnej generacji klasy proxy. Klasyczne klasy proxy to przydatne dla aplikacji lub biblioteki, która musi zapewnić bezpieczną dla typu transmisję od wezwania na obiekty, które obecny interfejs API enter image description hereDlaczego używamy dynamicznego proxy

Powyższy obrazek jest dobry przykład, ale dlaczego używamy dynamicznego proxy?

Czy istnieje jakiś prosty przykład, który można wykorzystać w prawdziwym świecie, aby uzyskać więcej percepcji?

+1

IMO to pytanie jest zbyt szerokie, powinieneś podzielić to pytanie w pojedynczych wydaniach – onof

+0

@onof Ok dzięki –

Odpowiedz

0

Ten link opisują dynamiczne proxy w kodzie:

public static class DynamicProxyGenerator 
{ 
    public static T GetInstanceFor<T>() 
    { 
     Type typeOfT = typeof(T); 
     var methodInfos = typeOfT.GetMethods(); 
     AssemblyName assName = new AssemblyName("testAssembly"); 
     var assBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assName, AssemblyBuilderAccess.RunAndSave); 
     var moduleBuilder = assBuilder.DefineDynamicModule("testModule", "test.dll"); 
     var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "Proxy", TypeAttributes.Public); 

     typeBuilder.AddInterfaceImplementation(typeOfT); 
     var ctorBuilder = typeBuilder.DefineConstructor( 
        MethodAttributes.Public, 
        CallingConventions.Standard, 
        new Type[] { }); 
     var ilGenerator = ctorBuilder.GetILGenerator(); 
     ilGenerator.EmitWriteLine("Creating Proxy instance"); 
     ilGenerator.Emit(OpCodes.Ret); 
     foreach (var methodInfo in methodInfos) 
     { 
      var methodBuilder = typeBuilder.DefineMethod( 
       methodInfo.Name, 
       MethodAttributes.Public | MethodAttributes.Virtual, 
       methodInfo.ReturnType, 
       methodInfo.GetParameters().Select(p => p.GetType()).ToArray() 
       ); 
      var methodILGen = methodBuilder.GetILGenerator();    
      if (methodInfo.ReturnType == typeof(void)) 
      { 
       methodILGen.Emit(OpCodes.Ret); 
      } 
      else 
      { 
       if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum) 
       { 
        MethodInfo getMethod = typeof(Activator).GetMethod(/span>"CreateInstance",new Type[]{typeof((Type)});       
        LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType); 
        methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType); 
        methodILGen.Emit(OpCodes.Call, typeofype).GetMethod("GetTypeFromHandle")); )); 
        methodILGen.Emit(OpCodes.Callvirt, getMethod); 
        methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType); 

       } 
       else 
       { 
        methodILGen.Emit(OpCodes.Ldnull); 
       } 
       methodILGen.Emit(OpCodes.Ret); 
      } 
      typeBuilder.DefineMethodOverride(methodBuilder, methodInfo); 
     } 

     Type constructedType = typeBuilder.CreateType(); 
     var instance = Activator.CreateInstance(constructedType); 
     return (T)instance; 
    } 
} 
+0

To jest specyficzna implementacja C#, ale nie mówi do możliwych aplikacji o f wzór – STW

+0

Jak już powiedziałem: Ten link opisuje dynamiczny serwer proxy w kodzie. i sprawiło, że stało się to dla mnie jasne, więc pomyślałem, że może to być dobra praktyczna odpowiedź na to pytanie. –

3

Typowym przykładem zastosowania jest Aspect-Oriented Programming, w którym dąży się do stosowania wspólnej funkcjonalności w wielu komponentach bez konieczności stosowania samych komponentów do implementacji funkcji. W takich przypadkach możesz użyć dynamicznego proxy, aby zawinąć wszystkie komponenty kierowania z dodatkowym zachowaniem. Czyniąc to

A kilka przykładów:

  • ORMs takich jak hibernacja i Entity Framework to zrobić, aby zapewnić realizację trwałości wokół projektowania kodu pierwszego. Podstawowe klasy domen są budowane bez żadnej wiedzy o ich trwałości, a frameworki owijają lub rozszerzają te klasy podczas uruchamiania, aby obsłużyć rzeczywistą implementację.

  • Zawijanie wszystkich elementów interfejsu z aspektem, na przykład rejestrowaniem lub buforowaniem. Na przykład, jeśli chcesz rejestrować każde wywołanie metody w interfejsie ISomeInterface, możesz napisać dynamiczny serwer proxy, który znajdzie wszystkie metody interfejsu, wywoła metodę Log z danymi metody, a następnie przekaże wywołanie do rzeczywistej implementacji.

2

Wyobraź sobie, że masz dwa obiekty Car and Motorboat, które implementują odpowiednio interfejsy CanDrive i CanFloat. Teraz chcesz mieć trzeci obiekt, który implementuje oba te interfejsy i który ponownie wykorzystuje logikę z samochodu i motorówki. W językach takich jak Groovy, Ruby i Scala można to rozwiązać za pomocą mixin. W Javie nie ma czegoś takiego. Można oczywiście użyć np. Wzór wzornika adaptera, ale w wielu przypadkach (szczególnie podczas budowania frameworków) dynamiczny serwer proxy przydaje się. Rozważmy przykład, który używa cglib Biblioteka:

CanDrive car = new Car(); 
CanFloat motorboat = new Motorboat(); 

net.sf.cglib.proxy.Mixin amphibian = net.sf.cglib.proxy.Mixin.create(new Object[] { car, motorboat }); 

TestCase.assertEquals("bzzz bzzz bzzz ...", ((CanFloat) amphibian)._float()); 
TestCase.assertEquals("pyr pyr pyr pyr ...", ((CanDrive) amphibian).drive()); 
Powiązane problemy