clojureclojureclr

Clojure CLR - Implement interface that contains properties


I'm trying to implement an interface that has properties but can't quite seem to get it to work and I also have not found any relevant examples via Google (yet). I'm sure I'm doing something completely wrong here but have no idea how to fix it.

(System.Reflection.Assembly/LoadWithPartialName "System.Web")

; naive, just trying to figure out how to implement the IHttpHandler interface in Clojure 
(defn foo-handler []
    (reify System.Web.IHttpHandler
        (IsReusable [] false)
        (ProcessRequest [context] ())))

IsReusable is a property and I don't know how to tell reify that it is not a traditional function.

CompilerException clojure.lang.CljCompiler.Ast.ParseException: Must supply at least one argument for 'this' in: IsReusable

Okay, I supply 'this' for IsReusable

CompilerException clojure.lang.CljCompiler.Ast.ParseException: Can't define method not in interfaces: IsReusable

I've also tried proxy but I get similar results.

I've also tried naming IsReusable to get_IsReusable which doesn't actually make a difference and I get the same compiler errors as above.

I've also tried deftype but I get a completely different error:

(deftype foo-handler []
  System.Web.IHttpHandler
  (get_IsReusable [this] false)
  (ProcessRequest [this context] ()))

Compiler error:

InvalidCastException Unable to cast object of type 'clojure.lang.Var' to type 'System.Type'.  clojure.lang.Namespace.ReferenceClass 

Update:

The code posted for deftype works, I cannot reproduce the error that I posted above. I have no idea now what I was doing wrong at the time.


Solution

  • This took me a few hours of research and trial and error but I finally have success!

    user=> (def foo-handler
    (reify System.Web.IHttpHandler
            (get_IsReusable [this] false)
            (ProcessRequest [this context] ())))
    #'user/foo-handler
    user=>
    

    Success!

    user=> (instance? System.Web.IHttpHandler foo-handler)
    true
    

    This way is better and works fine from an ASP.NET application:

    (deftype foo-handler []
      System.Web.IHttpHandler
      (get_IsReusable [this] false)
      (ProcessRequest [this context] 
        (.Write (.Response context) "Hello, From Clojure CLR!")))