Start a new topic

Passing non-duocode objects to duocode objects

Let's take the same example from my first post:


 

using System;
 
namespace Company.Product.Presentation.Model
{
    public class UserInterface
    {
        protected readonly IApplicationService _applicationService;
 
        public UserInterface( IApplicationService appService) 
        {
            _applicationService= appService;
        }
 
//method
        public virtual void Execute()
        {
            //
            _applicationService.Execute();
        }
    }
  }

It is ok now if I also have an implementation od IApplicationService in c# and transpiled with DuoCode.

But if I make an implementation of IApplicationService in typescript/js and pass that object to the  UserInterface constructor it Will not work when the code in the Execute function tries to call the ExecuteSpecial.

Because it is transpiled into:


 

this._applicationService.Company$Product$Presentation$IApplicationService$ExecuteSpecial();

 

Of course the typescript object does not have that long name in its implementation,


 

class AppSvc implements IApplicationService{
  ExecuteSpecial(){
alert("Test");
}
}

 How will we resolve such problems?  



In order to create C# like delegate in TS, you should use $d.delegate() with target object binded and cast it to <OnReceivedDelegate>.

like this:

  

  var onReceiveDlg = <OnReceivedDelegate>$d.delegate(myHandler, target_obj);
  rgs.IConnection$set_OnReceived(onReceiveDlg);

  


Note, in DuoCode v1.1 (released by this month) we improved TS defintion of $d.delegate<TDelegate>(...) method, like this:

 

var delegate: { <TDelegate>(method: Function, target?: any): TDelegate; };

 

Hope this helps and feel free to ask more.

I've tried the generated d.ts and now my example code is no longer ts compilable with usage:

 

    var rgsConnection: IConnection;
    rgsConnection = new RgsConnection();

 I get:

Type rgsConnection is not assignable to IConnection because of types of property IConnection$Send are incompatible. Type "Function" is not assignable to type "(message:string)=>void".

I can fix that by changing the rgsConnection to:

IConnection$Send: (message:string)=>void = this.Send;

I then get same issue for the getOnReceived: Type "Function" is not assignable to type "()=>OnReceivedDelegate". The following code won't compile: 

        IConnection$get_OnReceived: () => OnReceivedDelegate =
        () => { return this.OnReceived; };

 Any hint how can I pass a function as an OnReceivedDelegate and vice versa in this sample?

 

Please try our latest DuoCode v1.0 with TypeScript support, and even hybrid C# + TypeScript projects.

Download it from: http://duoco.de/download

More info: http://blog.duoco.de/2015/06/23/duocode-bridging-the-gap-between-csharp-and-typescript/


Regarding your question:

In summary I want to pass a c# delegate to a js object that implements c# interface?


DuoCode will auto generate IConection and OnReceivedDelegate interfaces in .d.ts file, you must implement it in TS, similar to what you did with RgsConnection.


Passing C# delegate (which is actually a JS function + typeinfo + additional Delegate methods) is straightforward.

I hope this is clear and helpful.


Note: currently TS generation of delegates doesn't contain method parameters in .d.ts, we already fixed this in the coming version, but u still can call it from TS since it's a Function.

In other words, currently DuoCode generates:

export interface OnReceivedDelegate extends System.MulticastDelegate { }

instead of, more strongly typed:

export interface OnReceivedDelegate extends System.MulticastDelegate { (data: any): void }


This works(in typescript):


 

        IConnection$get_OnReceived: Function = () => { return this.OnReceived; };
        IConnection$set_OnReceived: Function = (value) => {
            this.OnReceived = value; return value;
        };

        get OnReceived(): (data: any) => void {
            return this._OnReceived;
        }

        set OnReceived(callback:(data:any)=>void) {
            this._OnReceived = callback;
        }
        private _OnReceived: (data: any) => void;

        private received(data: any) {
            if (this._OnReceived !== undefined) {
                this._OnReceived(data);
            };
        } 

 


Hi, have another question similar to this one. How can I implement a C# defined interface(transpiled) in ts/js that allows me to set a delegate(callback) to be called from the transpiled code?


Lets have this in c#:

 

    public interface IConnection
    {
        void Send(string message);
        OnReceivedDelegate OnReceived{get;set;}
    }

    public delegate void OnReceivedDelegate(object data);

 and now I have a ts/js implementation of this interface like this:


 

export class RgsConnection implements IConnection {
        srConnection: SignalR;
        constructor() {
        }
        public Start(url:string, callback: () => void)
        {...
        }
        IConnection$Send: Function = this.Send;
        IConnection$get_OnReceived: ?;
        IConnection$set_OnReceived: ?;

        public Send(message: string) {
            this.srConnection.send(message);
        }

        public OnReceived: (data: any) => void;
        //receive...
        private received(data: any): SignalR {
            if (this.OnReceived !== undefined) {
                this.OnReceived(data);
            };
            return this.srConnection;
        }  
    }

 

Now if I create this rgsConnection ts/js object in javascript code and I pass it to a transpiled js code I don't know how to implement IConnection$set_OnReceived since it provides a $d.delegate() from the c# transpiled code.? I hope it's clear enough? In summary I want to pass a c# delegate to a js object that implements c# interface.

Ok, thanks. I'm looking forward for the ts/d.ts features. The upper solution is not yet a solution, it couples ts/js code with generated code "internals"!


Thanks again.

You can and should add field in AppSvc like this:

     

class AppSvc implements IApplicationService{
  ExecuteSpecial() { ("Test"); }
  $Product$Presentation$IApplicationService$ExecuteSpecial: Function = this.ExecuteSpecial;
}

     

Also stay tuned to our next version release, we are going to support TypeScript and .d.ts files, which will very help in your case !!

Login or Signup to post a comment