Building a single entry point to a WCF service: need unified approach to return objects and collections
Subject says it all: I'm creating a secure and generic wrapper to access a WCF service transparently.
A little background:
what I have done is that I've created similar business classes definition both on server and client. The server-side contains the actual logic while the client side contains only method definitions. Additionally, the client-side classes derive from a SecureFactory which implements a Call method. The body of every method of each derived class contains only a call to Call method. This Call method is responsible for invoking the server service passing such things as to the type of business class and which of its method to invoke to perform the requested operation. This approach is being designed in order to simplify security checks by restricting passing of security information to only between SecureFactory and Server service. There are tuns of other benefits which you most of already aware of.
Now here's the issue: I'm stuck at as to how to return objects (especially arrays of objects) from Server to Call method? The server may return a single business object (DataContract applied) as well as list of such objects. Since it's a generic approach, I have only Object to be used as return type. Following is the Call method
public object Call(params object[] parameters) { var mb = (new StackFrame(1).GetMethod()); using (Proxy.ServerClient server = new Security.BO.Proxy.ServerClient()) { try { if (((MethodInfo)mb).ReturnType.IsGenericType) { var response = server.InvokeForList(SecurityManager.Current.SID, SecurityManager.Current.Token, mb.DeclaringType.ToString(), mb.Name, parameters); return response.Result.ToList(); } else { var response = server.Invoke(SecurityManager.Current.SID, SecurityManager.Current.Token, mb.DeclaringType.ToString(), mb.Name, parameters); return response.Result; } } catch (Exception ex) { System.Diagnostics.Debugger.Break(); } } return null; } server methods: public CollectionResponse InvokeForList(string SID, string token, string type, string method, object[] parameters) { // Validation here var t = assemblyBO.GetType(type, true); object BO = Activator.CreateInstance(t); var mi = t.GetMethod(method); if (mi == null) throw new MethodNotImplementedException("Method " + method + " could not be found on type " + t.ToString()); object res = mi.Invoke(BO, parameters); // Convert list to t[] object list = res.GetType().GetMethod("ToArray").Invoke(res, 开发者_开发问答new object[0]); // Error here! cannot convert t[] into object[] return new CollectionResponse((object[])list); } The other method Invoke(...) is similar accept it returns Response object instead of CollectionResponse. Here's the CollectionResponse class: (Response is similar:just it takes only one object) [DataContract] public class CollectionResponse { [DataMember] private Object[] _result; public Object[] Result { get { return _result; } } public CollectionResponse(Object[] result) { this._result = result; } }
Initially I was thinking to have only one Invoke for both lists and singleton – but failed with "Connection was closed unexpectedly." still I'm not able to achieve – how can I convert T[] into object[].
Do you have any suggestion to improve it, or any other way of achieving the same?
Thanks
I can see an immediate problem here. You are using reflection which is far less perfromant than the direct call.
For me, that is enough not to follow this route.
精彩评论