Category Archives: .Net

Self-maintaining documentation for HTTP Rest APIs

So, I’ve got an API. I probably want to expose the basics on usage to the public, but I sure as hell don’t want to write documentation. My solution? Self-documenting code. ❤ reflection.

There are a few base classes referenced that I'm using to determine items which are allowed to be accessible publicly, and some that aren't. Maybe my code sucks, whatever, but it works. It certainly makes a few assumptions about what & how you're doing things (like Get/Post method names for the accepted http verbs).

Anyhow, it works for me and spits out a fancy JSON object that can be inspected via fiddler or chrome dev tools, which is enough to at least get started with consuming a new API. Sure beats randomly trying URLs and input/outputs.

 [Unauthenticated]
     public class ConfigController : SiteApiController
     {
          public ConfigData Get()
          {
               var types = Assembly.GetAssembly(typeof(ContractBase))
                    .GetTypes().Where(x => x.IsClass 
                         && typeof(PublicItem).IsAssignableFrom(x) 
                         && x != typeof(PublicItem));
               var parser = new ObjectParser();
               var d = new Dictionary();
               foreach (var type in types)
               {
                  d.Add(type.Name,parser.ParseObject(type));
               }
               var etypes = Assembly.GetAssembly(typeof(ContractBase)).GetTypes().Where(x => x.IsEnum);
               var e = new Dictionary();
               foreach (var etype in etypes)
               {
                    e.Add(etype.Name, parser.ParseEnum(etype));
               }
               var controllers = Assembly.GetAssembly(typeof(SiteApiController))
                    .GetTypes().Where(x => typeof(SiteApiController).IsAssignableFrom(x) && x != typeof(SiteApiController));
               var m = new Dictionary();
               foreach (var c in controllers)
               {
                    m.Add("/api/" + c.Name.Replace("Controller", ""), parser.ParseController(c));
               }

               return new ConfigData() {Classes = d, Enums = e, Methods = m};
          }
          public class ConfigData
          {
               public dynamic Classes { get; set; }
               public dynamic Enums { get; set; }
               public dynamic Methods { get; set; }
          }
     }
internal class ObjectParser
     {
          public dynamic ParseObject(Type type)
          {
               var props =
                    type
                       .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty |
                                          BindingFlags.GetProperty).Where(prop =>
                         !Attribute.IsDefined(prop, typeof(NotPublicAttribute)))
                         .ToArray(); ;

               var dict = new Dictionary();
               foreach (var prop in props)
               {
                    dict[prop.Name] = GetReadableType(prop.PropertyType);
               }
               return dict;
          }
          private string GetReadableType(Type type)
          {
               string ptype = type.Name;
               if (type.IsGenericType)
                    {
                         ptype = ptype.Replace("`1", "";

                    }
               return ptype;
          }
          public dynamic ParseEnum(Type type)
          {
               var list = new List();
               foreach (var val in Enum.GetValues(type))
               {
                    list.Add(string.Format("{0} ({1})",Enum.Parse(type,val.ToString()).ToString(),((int)val).ToString() ));
               }
               return list;
          }

          public dynamic ParseController(Type type)
          {
               var methods = new List();
               string input = "none";
               string output = "none";
               bool typesSet = false;
               bool requiresSSL =
                    type.CustomAttributes.Any(x => x.AttributeType == typeof(RequireSSLAttribute));
               bool unAuthenticated =
                    type.CustomAttributes.Any(
                         x => x.AttributeType == typeof (UnauthenticatedAttribute));
               foreach (
                    var method in
                         type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
                    )
               {
                    methods.Add(method.Name);
                    if (!typesSet)
                    {
                         var parms = method.GetParameters();
                         if (parms.Any())
                              input = parms.First().ParameterType.Name;
                         var returnType = method.ReturnType;
                         output = returnType.Name;
                         typesSet = true;
                    }
               }
               return new
                    {
                         Methods = methods,
                         Input = input,
                         Output = output,
                         RequiresSSL = requiresSSL,
                         RequiresAuthentication = !unAuthenticated,
                    };

          }
     }

Tagged ,

Upcoming MVC4 talk

So, I’m giving a short (1h or less) MVC4 talk to my coworkers in a couple weeks.

-MVC: Defining the pattern
–How MVC != Asp.Net MVC
-MVC4 Goodies
–Device-specific views
—JQuery Mobile, view switcher (may be deferred to the MVC4 on Mobile talk)
–Async controller classes
–Web API
–Single-Page Applications
–Recipes (is this MVC4 or just happens to be bundled with it?)
–Azure?
-Not MVC4 but you should know anyway:
–SignalR
–Backbone.js, Knockout.js

Tagged , ,

AutoMapper is awesome, but ArgumentNullException on IEnumerable.Select pisses me off.

Let me start this off by saying:
I am way undereducated with AutoMapper. I’m fairly certain there is a more elegant way to accomplish this, but I did it my way for the following reasons:

1) I’m stubborn
2) I don’t want to create ValueResolver classes. I don’t know why exactly, but I prefer to just have maps.
3) I can’t rename any of my classes, nor can I change the structure. I’m stuck with what I have.
4) In my instance, I can’t create a map directly from the source type to the destination type – I need to keep the actual references.

The situation:
I have a large number of classes with one to many relationships. For example, let’s take three simple classes:

public class Person
{
     public IList Addresses { get; set; }
}

public class PersonAddress
{
     public Person Person { get; set; }
     public PhysicalAddress PhysicalAddress { get; set; }
}

public class PhysicalAddress
{
     public string City { get; set; }
}

public class DestinationList
{
     public IList<PhysicalAddress> Cities { get; set; }
}

So, I tried a few different methods, with varying results.

Attempt 1:

public static void CreatePersonAddressMap()
{
     AutoMapper.Mapper.CreateMap()
          .ForMember(dest => dest.Cities,
               config => config.MapFrom(person => person.Addresses.Select(add => add.PhysicalAddress)));
          //Throws null reference exception if person.Addresses is null! OH NOES!
}

Result: ArgumentNullException when person.Addresses is null.

Attempt 2:

public static void CreatePersonAddressMap()
{
     AutoMapper.Mapper.CreateMap()
          .AfterMap((person, dest) =>
          {
               if (person.Addresses != null)
                    dest.Cities = person.Addresses.Select(add => add.PhysicalAddress).ToList();
          });
          //This method works, but it's A) Ugly and B) fails the AssertConfigurationIsValid check.
          //I could add .ForMember(dest => dest.Cities, s=> s.Ignore()), but again that sucks
}

Result: Works for the actual mapping, even when person.Addresses is null. However, fails the AutoMapper.Mapper.AssertConfigurationIsValid check

Attempt 3: I thought for sure this would work; what else could the .Condition method be for?

public static void CreatePersonAddressMap()
{
     AutoMapper.Mapper.CreateMap()
          .ForMember(dest => dest.Cities,
               config =>
               {
                    config.Condition(person => person.Addresses != null);
                    config.MapFrom(
                    person => person.Addresses.Select(add => add.PhysicalAddress));
               });
               //This is the method that I thought would work, but the Condition feature is underdocumented, at
               //least in my undereducated opinion.
}

Result: ArgumentNullException when person.Addresses is null. Grr.

Attempt 4:

public static void CreatePersonAddressMap()
{
     AutoMapper.Mapper.CreateMap()
          .ForMember(dest => dest.Cities,
          config => config.MapFrom(
               person =>
                    person.Addresses == null ? null : person.Addresses.Select(add => add.PhysicalAddress)));
               //This is the method I went with. It's still ugly, but it's (i think) a bit easier to follow, and won't crash
               //the AssertConfigurationIsValid check.
}

Result: It works, doesn’t throw an exception, and correctly projects the desired information. However, I will readily admit that it is quite ugly and would much prefer a better option for the configuration of AutoMapper…. Or some advice on what I’m doing wrong. That works too.

Why doesn’t apple just show the network activity indicator?

So, for real: Why doesn’t apple just turn on the network activity indicator when there’s traffic? I find it silly that I have to manage that. I mean, beyond just single-connection scenarios, if I have some process (let’s say, a UITableView) that is going to download multiple items, now I have to manually monitor the number of threads in use, and when that hits zero shut the indicator off.

And if I don’t, Apple is quite likely to reject my app, as it does not adhere to the development guidelines/standards they set up.

It seems like something this trivial should be handled by the FRAMEWORK, since they won’t allow me to directly access the API that, I’m rather sure KNOWS when the network is in use.

That said, here’s some code to do it for you – just call AddNetworkConnection and RemoveNetworkConnection (you can do it in a simpler format, but this is the more awesome way with read and writer locks);


public static class Utility
{
private static ReaderWriterLock rwl = new ReaderWriterLock();
private  static int Connections = 0;

public static void AddNetworkConnection()
{
rwl.AcquireReaderLock(TimeSpan.FromSeconds(1)); //You don't actually have to check, you can just always set this to true
if (Connections == 0)  // but I like to be fancy.
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
rwl.UpgradeToWriterLock(TimeSpan.FromSeconds(1));
Connections++;
rwl.ReleaseLock();
}

public static void RemoveNetworkConnection()
{
rwl.AcquireWriterLock(TimeSpan.FromSeconds(1));
Connections--;
if (Connections < 0)
Connections = 0; //just in case, y'know?
if (Connections <= 0)
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
rwl.ReleaseLock();
}
}

And that’s it, you’ve got a simple way to keep the Network Activity indicator updated.
If I were more awesome, I’d find a way to attach it to the thread accessing the network, and automatically decrement the count. But, this way works with both blocking and non-blocking calls. So meh.

Emulating backgroundTap in Monotouch to hide keyboard

I searched and searched, and couldn’t figure out how to hide the keyboard when a user clicks on the view…

Finally, I dun figured it out on my own. It probably should be obvious to most, but here it is anyhow (place this in the code for your view controller):

public override void TouchesEnded (NSSet touches, UIEvent evt)
{
	foreach (var item in this) {
		var tf = item as UITextField;
		if (tf != null &amp;&amp; tf.IsFirstResponder) {
			tf.ResignFirstResponder ();
		}
	}
	base.TouchesEnded (touches, evt);
}

Unwire your events to make Garbage Collector happy.

In Monotouch, I have an application that was eating up a lot of memory. When digging into Instruments, I found that it was multiple copies of images being retained well past their needed lifetime.

Generally, I love me some anonymous delegates when invoking simple actions. That is,

someButton.TouchUpInside += delegate { DoSomething(); }

However, if you are swapping views often, this becomes problematic as the UIButton will not release the image from memory, even if you manually call .Dispose() on the button and its imageview and it’s imageview’s image.

So, to prevent that behavior, I moved to using explicit methods for the delegates. This way, I can manually unhook them from the object in the .Dispose() or my personal .Cleanup() methods. This allows the button to be completely disposed and GC to work as expected. Without the underlined snippet below, I was seeing memory usage explode – to the tune of 100s of images being loaded (even though there are only ~16 images in total, and never more than 4 displayed at once).
Sample:


public UIImage image;
public override void ViewDidLoad ()
{
	this.button.SetImage(image,UIControlState.Normal);
	this.button.TouchUpInside += HandleButtonhandleTouchUpInside;
}
int Z;
void HandleButtonhandleTouchUpInside (object sender, EventArgs e)
{
	var x = 13;
	var y = 12;
	var z = x + y;
	Z = z;
}
public void Cleanup()
{
	this.button.TouchUpInside -= HandleButtonhandleTouchUpInside;
	this.button.Dispose();
	base.Dispose();
}

Aborting an NSTimer in MonoTouch

It’s really easy: timer.Invalidate();
Not being accustomed to timers, I was looking for an .Abort() method. But, it seems that Invalidate encompasses the same function.

Of course, that means you have to keep a reference around. This is in reference to my previous post about checking the fire date of a timer – It wasn’t working quite perfectly for me, so I ended up invalidating it, then initializing a new timer instance to fire the event in the future. And now, somehow, I managed to make it work.

In related news: Having too many UIView animations can cause some interesting things to happen – views showing or hiding when they’re not supposed to, random “ghost” images of your view… etc etc. Be sure to clean up and keep track of everything in the timeline when using UIView Animations.

Final Code:

private NSTimer timer;
void DoStuff()
{
	if (timer != null &&  timer.IsValid)
	{
		timer.Invalidate();
	}
	timer = NSTimer.CreateScheduledTimer(4,ReallyDoStuff);
}

Multiplayer in MonoTouch

The easy way is to use GameKit, good starting article at :

http://mikebluestein.wordpress.com/2010/06/14/using-gamekit-with-monotouch-2/

Though what I *really* want to do is create an ad-hoc wifi network… So far it seems that apple has restricted devs to only access existing wifi networks (IE you aren’t allowed to create your own ad-hoc network on the iphone). I’m assuming this is a “feature” designed to make it more difficult to find a way to tether your iPhone to another device.

Oh well. Buzzwordingo should have chat capabilities soon enough.

What AutoMapper needs.

private TDestination AutoMap<TSource, TDestination>(TSource source)
{
     if (Mapper.FindTypeMapFor(typeof(TSource), typeof(TDestination)) == null)
     {
          Mapper.CreateMap(typeof(TSource), typeof(TDestination));
     }
     return Mapper.Map<TSource, TDestination>(source);
}

That way, I don’t have to trap an exception with Mapper.DynamicMap.

Polerecky doesn’t like it, but I still do.

What happens when your iPhone App gets updated via iTunes/app store?

Well, all the data files in core data & personal folders within the app’s isolated storage are NOT cleared out. So, if you’re doing something crazy like serializing data to a a file and you change the class structure, make sure you find a way to version it.

Also, probably not a great idea to version it by filename, since you’ll never clear out the old, unused ones. I like using a Version property and checking against that. Simple, effective.

Also, MonoTouch rocks at serializing POCO objects into files. In this case, it’s the custom word list for my iPhone app Buzzwordingo. The quickest way I found to allow custom lists? Serialize a List<string> to a file. Deserialize, update, Serialize.

I will also be using this serialization technique to add board-state persistence, so that @detroitpro will stop whining.

Tagged