Implementing command at client, executing it at sever
I'm implementing a WCF service and I want to implement it in such a way that the clients should be able to execute commands on the server, even though the implementation of the command isn't present on the server.
The code should look something like this:
//Common interface - used by both client and server
public interface ICommand
{
//add whatever method/property is needed to achieve the goal
}
//Server side interface and implementation
[ServiceContract()]
public interface ICommandChannel
{
[OperationContract]
object ExecuteCommand(ICommand command, Guid clientId);
}
public class CommandExecutor : ICommandChannel
{
object ExecuteCommand(ICommand command, Guid clientId)
{
//this should be able to execute any command clients send
}
}
//Client side commands implementation
public class FileUploadCommand : ICommand
{
}
public class AuthorizeUSerCommand : ICommand
{
}
public class SubmitChangesCommand : ICommand
{
}
//etc
If it was 开发者_开发技巧allowed to serialize methods, then the solution would have been very straightforward, as we could serialize Execute
method (and other methods) defined in ICommand
, send it through the channel, and deserialize it on the server, and call the Execute
method. But that is not possible, because serialization of method isn't allowed (as far as I know).
So my question is, is there any solution to this problem? Can expression tree help here?
EDIT:
I cannot let the server know the implementation. Because if I do so, then I've to build and deploy the service everytime I add new commands on the client side. Or am I missing anything?
Expression trees are not easily serialized, and even if they were, the 4.0 extensions to allow more method-like usage are not supported by the expression compiler, so creating the expressions would be very tricky.
Additionally, allowing arbitrary code execution is not something to be taken lightly - there are lots of security implications.
Personally, I suspect your best bet would be to let the server know the implementation (in advance) perhaps via assembly sharing (so the contract classes at the client and server are identical, loaded from a library dll). However, another option may exist via scripting languages - maybe you could write the method in iron-python? You could also use C# and compile on the fly - but I repeat my warning: running input as code on a server? not very safe.
精彩评论