www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Create a proxy

reply Voitech <woipoi gmail.com> writes:
Hi, I'm trying to create a proxy with automatic method generation 
. Let say i hava Service object which can be Local service and 
Remote service. f.e:
interface Service{
    string serviceInfo();

}
interface LocalService:Service{

    int doSmth(string param);

}
class LocalServiceImpl:LocalService{

    override string serviceInfo(){
       return "i am local";
    }
    override int doSmth(string param){
       return param.lenght;
    }
}
And now i want to create a proxy, which for client is visible as 
LocalService

class RemoteServiceProxy:LocalService{

   Serializer serializer;
   HttpClient client;
   Deserializer deserializer
   this(Serializer serializer,Deserializer deserializer,HttpClient 
client){
      this.serializer=serializer;
      this.client=client;
      this.deserializer=deserializer;
   }

    override string serviceInfo(){
       return "i am remote";
    }
    override int doSmth(string param){
       string json= serializer.toJson!(doSmth,int,param)();
       string response=client.send(json);
       return deserializer.fromJson!(response,int)();
    }

}
So RemoteServiceProxy should serialize method name, return type 
and parameters and send it to some server. On server this should 
be executed (for now i don't care about errors) and returned as 
proper value.

The problem is i don't want to override every remote service 
method i will create in interface (LocalService) i want them to 
be generated depending on return, and parameter types. It will 
always the same schema: serialize ... http request ... 
deserialize ... return value (throw Excepion).

How to handle this corectly ? I was trying to use mixins for this 
i created some functions but this not working don't know why

string createFunction(R, alias name)(){

	static if(is(R==void)){
		return mixin(createVoidFunction(name)());
	}
	static if(!is(R==void)){
		return mixin(createNonVoidFunction!(R,name)());
	}
}

string createVoidFunction(alias name)(){
	return format(q{
			void %s(){
				writeln(" im void function");
			}
		},name);
}
string createNonVoidFunction(R,alias name)(){
	return format(q{
			%s %s(){
				writeln("im non void function");
				return %s;
			}
		}, R.stringof,name,R.init);
}


unittest{
	mixin(createFunction!(int,"nonVoid")());
}

There is also a Proxy template in std.typecons but i don't 
understand how it works or even can it be used in this case. How 
to handle this ?
Feb 19 2016
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/19/2016 06:18 AM, Voitech wrote:

 I was trying to use mixins for this i
 created some functions but this not working don't know why
Compilation errors or something else? pragma(msg) helps with debugging generated code. You can also use unittest blocks to make sure that the generated code is what you expect.
 There is also a Proxy template in std.typecons but i don't understand
 how it works
That one makes a user-defined type to be used as another type. The example from the documentation is MyInt behaves exactly like an int by forwarding int operations to 'value': struct MyInt { private int value; mixin Proxy!value; this(int n){ value = n; } } MyInt n = 10; Support for all the following operations (++, ==, *, and more) are mixed in by Proxy: // Enable operations that original type has. ++n; assert(n == 11); assert(n * 2 == 22); Ali
Feb 19 2016