Search Unity

Unity3D + AOP

Discussion in 'Scripting' started by PrefabEvolution, Sep 5, 2014.

  1. PrefabEvolution

    PrefabEvolution

    Joined:
    Mar 27, 2014
    Posts:
    225
    When you are using AOP you should ever notify AOP framework when your assemblies are changed. While Unity doesn't provide any API to handle script compilation done, you can use this code to do so.
    Code (csharp):
    1.  
    2. using UnityEditor;
    3. using UnityEngine;
    4. using System.IO;
    5. using System.Collections.Generic;
    6.  
    7. [InitializeOnLoad]
    8. static class AssemblyPostProcessor
    9. {
    10.     //Keep list of watchers to prevent GC collect
    11.     static public List<FileSystemWatcher> watchers = new List<FileSystemWatcher>();
    12.  
    13.     static AssemblyPostProcessor()
    14.     {
    15.         Debug.Log("Init AssemblyPostProcessor");
    16.         RigisterOnFileChanged(Application.dataPath + "/../Library/ScriptAssemblies/Assembly-CSharp.dll", DoInject);
    17.     }
    18.        
    19.     static void DoInject(string path)
    20.     {
    21.         Debug.Log("Inject dll " + path);
    22.         //Inject code here...
    23.         Debug.Log("Inject dll Done");
    24.     }
    25.  
    26.     static public void RigisterOnFileChanged(string path, System.Action<string> action)
    27.     {
    28.         Debug.Log("Watch: " + Path.GetFullPath(path));
    29.  
    30.         var fileSystemWatcher =
    31.             new FileSystemWatcher(Path.GetDirectoryName(path))
    32.         {
    33.             EnableRaisingEvents = true
    34.         };
    35.  
    36.         fileSystemWatcher.Changed +=
    37.             (o, e) =>
    38.         {
    39.             Debug.Log("File changed:" + e.FullPath);
    40.             if(Path.GetFullPath(e.FullPath) == Path.GetFullPath(path))
    41.             {
    42.                 action(path);
    43.             }
    44.         };
    45.         watchers.Add(fileSystemWatcher);
    46.     }
    47. }
    48.  
     
    Last edited: Sep 5, 2014
    SkorpionX likes this.
  2. Xtro

    Xtro

    Joined:
    Apr 17, 2013
    Posts:
    608
    Hi, I'm very interested in AOP in Unity. I tried Postsharp and SNAP but failed to make them work. Actually Postsharp work well if I build my classes into a separate dll and import that dll into Unity. But I want to be able to use AOP without implementing separate dlls.

    In your example, you showed how to catch the dll built by Unity but you didn't actually show how to inject code into it and how to implement a real AOP solution.

    Do you have any more examples about method intercepting and implementing aspect attributes?

    My first AOP goal is to implement parameter validation on methods via an attribute. Do you think you can help me?
     
  3. Patico

    Patico

    Joined:
    May 21, 2013
    Posts:
    886
  4. Xtro

    Xtro

    Joined:
    Apr 17, 2013
    Posts:
    608
  5. WaylandGod

    WaylandGod

    Joined:
    Jul 23, 2015
    Posts:
    7
    @PrefabEvolution, I just study this recently, but I didn't realize it in unity3d. Do you have more demo code? Thanks.
    @Xtro, Can you share me your example code? My email: 1150987263@qq.com. Thanks.
     
  6. Xtro

    Xtro

    Joined:
    Apr 17, 2013
    Posts:
    608
    My example code about what?
     
  7. WaylandGod

    WaylandGod

    Joined:
    Jul 23, 2015
    Posts:
    7
    I just make it in VS without U3D. And you said, you succeed by building the classes in Dll and then using it in U3D. So can you share me this detail method or show me the example code? Thanks.
     
  8. Xtro

    Xtro

    Joined:
    Apr 17, 2013
    Posts:
    608
    Oh I got it now.

    I tested and saw that it works but I never implemented anything on it because I'm very bust with my office work.

    Basically, this is what I did...

    1) Create a regular VS c# dll project.
    2) Install postsharp on it.
    3) Include an aspect attribute class into the project (an example attribute from postsharp site)
    4) Add a debug.log into entry event of the aspect.
    5) Decorate one of my monobehaviour methods (in dll project) with that aspect.
    6) Compile the dll. (In this step, postsharp injects its magic into the dll)
    7) Include the dll into unity project.
    8) Make sure the decorated method is called in runtime.
    9) See that the debug.log call in the aspect entry event outputs text to unity console.
     
  9. WaylandGod

    WaylandGod

    Joined:
    Jul 23, 2015
    Posts:
    7
    Thanks very much, but there's a problem here for I misunderstood your words.
    I thought you imported the compiled U3D Dlls into vs, and did the static injection there, then finally imported back to U3D...
    And if you have any progress on this topic, give me a message please, thanks, I will keep concern.
     
  10. Xtro

    Xtro

    Joined:
    Apr 17, 2013
    Posts:
    608
    No. Postsharp doesn't support mono generaged dlls.
     
  11. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    I've been looking into something like this, may just roll my own post-process framework with Mono.Cecil.
     
  12. WaylandGod

    WaylandGod

    Joined:
    Jul 23, 2015
    Posts:
    7
    I haven't read the documents in detail, but I didn't use mono but vs build the Dlls.
     
  13. Xtro

    Xtro

    Joined:
    Apr 17, 2013
    Posts:
    608
    Unity compiles your scripts using mono compiler. So DLLs which are generated by Unity (by mono) isn't supported by postsharp.

    Only way to use postsharp in your unity project is:
    1) Writing your scripts directly in visual studio as a "class library project"
    2) Compile it into a DLL (Postsharp injects itself to dll in this step)
    3) Import the dll into your unity project (not the source files)

    I haven't watched the whole video but this demonstrates how you do it :


    Please note that, that video only covers how to include your scripts into a dll. It doesn't cover postsharp or something.