Acr.ExtDirect – Part 1 – Method Resolvers
- by Allan Ritchie
One of the most important things of any open source libraries in my opinion is to be as open as possible while avoiding having your library become invasive to your code/business model design. I personally could never stand marking my business and/or data access code with attributes everywhere. XML also isn’t really a fav with too many people these days since it comes with a startup performance hit and requires runtime compiling. I find that there is a whole ton of communication libraries out there currently requiring this (ie. WCF, RIA, etc). Even though Acr.ExtDirect comes with its own set of attributes, you can piggy-back the [ServiceContract] & [OperationContract] attributes from WCF if you choose. It goes beyond that though, there are 2 others “out-of-the-box” implementations – Convention based & XML Configuration. Convention – I don’t actually recommend using this one since it opens up all of your public instance methods to remote execution calls. XML Configuration – This isn’t so bad but requires you enter all of your methods and there operation types into the Castle XML configuration & as I said earlier, XML isn’t the fav these days. So what are your options if you don’t like attributes, convention, or XML Configuration? Well, Acr.ExtDirect has its own extension base to give the API a list of methods and components to make available for remote execution. 1: public interface IDirectMethodResolver {
2:
3: bool IsServiceType(ComponentModel model, Type type);
4: string GetNamespace(ComponentModel model);
5: string[] GetDirectMethodNames(ComponentModel model);
6: DirectMethodType GetMethodType(ComponentModel model, MethodInfo method);
7: }
Now to implement our own method resolver:
1: public class TestResolver : IDirectMethodResolver {
2:
3: #region IDirectMethodResolver Members
4:
5: /// <summary>
6: /// Determine if you are calling a service
7: /// </summary>
8: /// <param name="model"></param>
9: /// <param name="type"></param>
10: /// <returns></returns>
11: public bool IsServiceType(ComponentModel model, Type type) {
12: return (type.Namespace == "MyBLL.Data");
13: }
14:
15: /// <summary>
16: /// Return the calling name for the client side
17: /// </summary>
18: /// <param name="model"></param>
19: /// <returns></returns>
20: public string GetNamespace(ComponentModel model) {
21: return model.Name;
22: }
23:
24: public string[] GetDirectMethodNames(ComponentModel model) {
25: switch (model.Name) {
26: case "Products" :
27: return new [] {
28: "GetProducts",
29: "LoadProduct",
30: "Save",
31: "Update"
32: };
33:
34: case "Categories" :
35: return new [] {
36: "GetProducts"
37: };
38:
39: default :
40: throw new ArgumentException("Invalid type");
41: }
42: }
43:
44: public DirectMethodType GetMethodType(ComponentModel model, MethodInfo method) {
45: if (method.Name.StartsWith("Save") || method.Name.StartsWith("Update"))
46: return DirectMethodType.FormSubmit;
47:
48: else if (method.Name.StartsWith("Load"))
49: return DirectMethodType.FormLoad;
50:
51: else
52: return DirectMethodType.Direct;
53: }
54:
55: #endregion
56: }
And there you have it, your own custom method resolver. Pretty easy and pretty open ended!