Advertisement
Guest User

Untitled

a guest
Dec 10th, 2013
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.62 KB | None | 0 0
  1. open System
  2. open System.Linq
  3. open System.Net
  4. open System.Reflection
  5. open System.Reflection.Emit
  6. open System.Collections.Generic
  7.  
  8. [<AttributeUsage(AttributeTargets.Class, AllowMultiple = false)>]
  9. type public LoggingAttributeAttribute (t : Type) =
  10.     inherit Attribute()
  11.     member public this.AttachedType
  12.         with get() = t
  13.  
  14. [<LoggingAttribute(typeof<MyClass>)>]
  15. type public MyClass () =
  16.     class
  17.         abstract member DoStuff : unit -> string
  18.         default this.DoStuff () =
  19.             "hello world"
  20.     end
  21.  
  22. type ExtendedMyClassDoStuffDelegate =
  23.     delegate of unit -> string
  24.  
  25. (*
  26. let GenerateLogging (attrs : LoggingAttributeAttribute seq) =
  27.  
  28.     let types = Seq.map (fun (attr : LoggingAttributeAttribute) -> attr.AttachedType) attrs
  29.  
  30.     let asmName = new AssemblyName "myAssembly"
  31.     let ab = AppDomain.CurrentDomain.DefineDynamicAssembly (asmName, AssemblyBuilderAccess.Run)
  32.     let mb = ab.DefineDynamicModule asmName.Name
  33.  
  34.     for t in types do
  35.         let name = t.Name
  36.         let methods = t.GetMethods (BindingFlags.Public ||| BindingFlags.DeclaredOnly ||| BindingFlags)
  37.         let tb = mb.DefineType ("Extended" + name, TypeAttributes.Public, t)
  38.         let cb = tb.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, Array.empty)
  39.         let cbIl = cb.GetILGenerator ()
  40.         cbIl.Emit OpCodes.Ldarg_0
  41.         cbIl.Emit (OpCodes.Call, typeof<MyClass>.GetConstructor Type.EmptyTypes)
  42.         cbIl.Emit OpCodes.Ret
  43.         for m in methods do
  44.             let methodName = m.Name
  45.             let mb = tb.DefineMethod (methodName, MethodAttributes.Public ||| MethodAttributes.HideBySig ||| MethodAttributes.Virtual ||| MethodAttributes.NewSlot, m.
  46.  
  47.  
  48.  
  49.  
  50.     0
  51.  
  52. *)
  53. [<EntryPoint>]
  54. let main args =
  55.    
  56.     let attrs =  [|
  57.                     for x in (Attribute.GetCustomAttributes(Assembly.GetEntryAssembly(), typeof<LoggingAttributeAttribute>))  
  58.                         do yield x :?> LoggingAttributeAttribute
  59.                  |]
  60.                
  61.  
  62.     let asmName = new AssemblyName "myAssembly"
  63.     let ab = AppDomain.CurrentDomain.DefineDynamicAssembly (asmName, AssemblyBuilderAccess.Run)
  64.     let mb = ab.DefineDynamicModule asmName.Name
  65.     let tb = mb.DefineType ("ExtendedMyClass", TypeAttributes.Public, typeof<MyClass>)
  66.    
  67.     let cb = tb.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, Array.empty)
  68.     let cbIl = cb.GetILGenerator ()
  69.     cbIl.Emit OpCodes.Ldarg_0
  70.     cbIl.Emit (OpCodes.Call, typeof<MyClass>.GetConstructor Type.EmptyTypes)
  71.     cbIl.Emit OpCodes.Ret
  72.  
  73.    
  74.     let mbDoStuff =
  75.         tb.DefineMethod ("DoStuff", MethodAttributes.Public ||| MethodAttributes.HideBySig ||| MethodAttributes.Virtual ||| MethodAttributes.NewSlot, typeof<string>, Type.EmptyTypes)
  76.     let ilDoStuff = mbDoStuff.GetILGenerator ()
  77.    
  78.     ilDoStuff.Emit OpCodes.Ldarg_0
  79.     ilDoStuff.Emit(OpCodes.Ldstr, "Calling base `DoStuff'")
  80.     ilDoStuff.Emit (OpCodes.Call, typeof<Console>.GetMethod ("WriteLine", [| typeof<string> |]) )
  81.     ilDoStuff.Emit (OpCodes.Callvirt, typeof<MyClass>.GetMethod "DoStuff")
  82.     ilDoStuff.Emit OpCodes.Ret
  83.    
  84.     let myDynamicType = tb.CreateType ()
  85.     let extendedMyClass = Activator.CreateInstance myDynamicType
  86.    
  87.     let del = Delegate.CreateDelegate (typeof<ExtendedMyClassDoStuffDelegate>, extendedMyClass, "DoStuff")
  88.     let extendedMyClassDoStuff = del :?> ExtendedMyClassDoStuffDelegate
  89.  
  90.     let myClass = new MyClass ()
  91.  
  92.  
  93.     [myClass.DoStuff; extendedMyClassDoStuff.Invoke]
  94.     |> List.map (fun del -> del() )
  95.     |> List.iter (fun str -> printfn "%s" str)
  96.    
  97.  
  98.     0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement