Binding method names declaratively? - reflection

Finding the need to be able to get method names in a declarative manner (for AOP, reflection, etc) such that compiler checking enforces breaking changes etc. Good example:
invocation.Method.Name.Equals("GetAll"
.. is there a way to do this like with a lambda/generic method so i don't have to put the method name as a string literal?
I've used things like this before to get property names:
public static string GetPropertyName<T, P>(Expression<Func<T, P>> propSelector)
where T : class
{
return (propSelector.Body as MemberExpression).Member.Name;
}
.. but is there a reliable and easy way to do the same for methods?

You can do something like this with delegates:
public static string MethodName(Delegate d) {
return d.Method.Name;
}
// and to use...
MethodName(new Func<object, int>(Convert.ToInt32));
If there's a particular delegate signature you use, you can create specific overloads:
public static string MethodName(Func<object, int> d) {
return MethodName((Delegate)d);
}
MethodName(Convert.ToInt32);
You might also be able to do something with generics, if you have a play around with it.

Related

Simplest way to use composed object as RequestParam in Spring

To following is something like... pseudo code... To illustrate what I am looking for:
// Setters and Getters ommitted to keep the example short here:
class Address
{
private String street;
private String city;
}
class AddressBookEntry
{
private String name;
private Address address;
}
class MyController
{
public void render(#RenderParam AddressBookEntry entry)
{
...
}
}
As you can see there are two POJOs (Address and AddressBookEntry). Now I would like to pass an AddressBookEntry to my Controller as http request parameter. I imagine that the URL looks like this: /target?entry.name=Random-Guy&entry.address.street=Random-Street&entry.address.city=Random-City.
As far as I understand #RenderParam doesn't work this way. I would have to create a PropertyEditor that takes a single string and construct my target Object from it, which means that I can't have an individual URL-param for each (sub-)property.
#ModelAttribute comes closer, but I could not find any hint if and how nesting of objects might work with this annotation. Additionally this annotation works without the "entry." prefix in my URL above which means that I need to make sure that I don't have multiple ModelAttributes that share a property name, correct? That sounds stressful.
How can I solve this?
It's the situation when you should use #ModelAttribute. It supports nested objects as you want.
If you need multiple #ModelAttributes, you can compose them into special class (for example, it you case that class can contain a field named entry of type AddressBookEntry, so that parameter names will be the same).

ASP.net how to extend a control or collection

I am attempting to extend a List. When using Visual Studio there are the different code hints for all the functions I can use with a List object. How can I extend the functionality of the List to show my new function?
public class ListExtensionHelper<T> : System.Collections.Generic.List<T>
{
public List<T> AwesomeFunction<T>()
{
}
}
For the life of me I could not find anything online on how I would do it for a List
If you are trying to add AwesomeFunction as an extension method to a regular List object, then you need to define an extension method in a static class:
public static class ListExtensions
{
public static List<T> AwesomeFunction<T>(this List<T> list)
{
}
}
Otherwise, the code you have should work; if you instantiate the ListExtensionHelper class, it should have all the functions of List as well as AwesomeFunction.
It sounds like you're looking for extension methods, rather than inheritance.
There are some really good examples here. There's also a really good library of extensions available here.
<soapbox>
One of my personal favorites that I use is this:
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string s)
{
return string.IsNullOrEmpty(s);
}
}
It's ridiculously simple, but a huge pet peeve of mine is having to write:
if (string.IsNullOrEmpty(someVariable))
as opposed to:
if (someVariable.IsNullOrEmpty())
For me it's just a matter of being a natural construct of my native language. The built-in method sounds like:
object verb subject
whereas mine sounds like:
subject verb
It's probably silly, but when I want to act upon a subject it just makes more sense for me to start with the subject :)
</soapbox>

asp.net webservice object manipulation

Possibly not specific to webservices, but...
I have a webmethod that returns:
List<Tadpole> myList = getList();
return new { data = myList , count = 5 };
It returns this as JSON.
my code checks myList[x].fishsticks which isn't actually part of the Tadpole class (so it errors). I am wondering, can I add a fishsticks attribute to myList somehow to avoid the error, so it gets included when I return the data?
Is there perhaps another elegant solution for doing this?
In your example, you'll have to add a fishsticks property to Tadpole.
public class Tadpole
{
//....
public int Fishsticks { get; set; }
}
Also, why are you adding a .Count property to your JSON type? Wouldn't it make more sense to just .data.Count, or just return the list and skip the wrapper entirely?
I haven't checked what properties of List<> get serialized lately, so it's possible that it's not included, but even if that's the case it would make more sense to do this:
List<Tadpole> myList = getList();
return new { data = myList , count = myList.Count };
Or, create a descendant class that overrides .Count and adds a serialization attribute.
Edit
If I remember correctly, anonymous/dynamic types are internally implemented as dictionaries, while classes are, well, not. (BTW, anonymous types and dynamic objects bring a host of performance and maintenance issues along with them.)
If you don't want to modify Tadpole for some reason, you could always create a descendant class:
public class HungryTadpole : TadPole
{
public int FishSticks { get; set; }
}
Strong typing is your friend and will save you many headaches down the road.

strongly typed sessions in asp.net

Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions
http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx
http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx
http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx
and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics
public static class SessionManager<T> where T:class
{
public void SetSession(string key,object objToStore)
{
HttpContext.Current.Session[key] = objToStore;
}
public T GetSession(string key)
{
return HttpContext.Current.Session[key] as T;
}
}
Is there any inherent advantage in
using
SessionManager<ClassType>.GetSession("sessionString")
than using
HttpContext.Current.Session["sessionString"] as ClassType
I was also thinking it would be nice
to have something like
SessionManager["sessionString"] = objToStoreInSession,
but found that a static class cannot have an indexer. Is there any other way to achieve this ?
My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.
public class SessionObject { public Type type {get;set;} public Object obj{get;set;} }
this would not work as well (as the return signature would be the same, but the return types will be different).
Is there any other elegant way of saving/retrieving objects in session in a more type safe way
For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.
A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.
I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.
You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html
Actually, if you were looking to type objects, place the type at the method level like:
public T GetValue<T>(string sessionKey)
{
}
Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).
Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:
public class SessionManager
{
private static SessionManager _instance = null;
public static SessionManager Create()
{
if (_instance != null)
return _instance;
//Should use a lock when creating the instance
//create object for _instance
return _instance;
}
public object this[string key] { get { .. } }
}
And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.
I posted a solution on the StackOverflow question is it a good idea to create an enum for the key names of session values?
I think it is really slick and contains very little code to make it happen. It needs .NET 4.5 to be the slickest, but is still possible with older versions.
It allows:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
to work exactly like:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;

How to find function parameters

I need to log all the function parameters in a dozen functions.
Is there a way to pro grammatically determine all the parameters and their values (or at least their .ToString() value)? Perhaps via reflection?
Here is an example of how to do this with PostSharp
http://consultingblogs.emc.com/merrickchaffer/archive/2009/08/04/using-postsharp-to-log-method-entry-and-exit-in-net-code.aspx
You can also roll your own
http://www.developerfusion.com/article/5307/aspect-oriented-programming-using-net/3/
To the best of my knowledge there's no way to use reflection to dynamically list and determine value of local variables. You can use reflection to get type information about the parameters of a method, but only the declared type - you can't automatically get information about the actual arguments, because the reflection metadata gives information about the method definition, not the specific values passed to it at runtime.
You can, however, do something like this:
static class Extensions
{
public static string GetTypeAndValue(this object obj)
{
return String.Format("{0}: {1}", obj.GetType().Name, obj.ToString());
}
}
Then, from within each method in which you want to perform logging, do something like
private void SomeMethodToBeLogged(string some_string, int some_int, bool some_bool)
{
Logger.Log(String.Format("SomeMethodToBeLogged({0}, {1}, {2})",
some_string.GetTypeAndValue(),
some_int.GetTypeAndValue(),
some_bool.GetTypeAndValue()));
}

Resources