# Sunday, November 25, 2007

Background Information

Aspect Oriented Programming has been on my list of things to read up on for almost a year now.  It likely would have stayed on my list of things to do well into the future if it hadn't been for a recent .NET Rocks episode.  I can't recall if it was the Pablo Castro on Astoria, or the Tim Sneath and Ian Ellison show, but one of them off-hand mentioned PostSharp.  As I usually do when links are thrown about on the show, I scribbled it on my hand for later review. Update DNR just released a show with Gael Fraiteur of PostSharp fame!

Once I got to the PostSharp site, I found their sample video on creating a trace AOP attribute.  They had me hooked.  I wasn't so much interested in doing a logging or trace attribute, but was more interested in doing a few validation attributes.  More specifically a NotNullAttribute.

The Problem

What got me interested in doing the NotNullAttribute was thinking back to how many times in our code base we would have something like this:

1 public void AddUser(Organization org, User user) 2 { 3 if (org == null) 4 throw new ArgumentNullException("org"); 5 if (user == null) 6 throw new ArgumentNullException("user"); 7 8 org.AddUser(user); 9 _ordDal.Save(org); 10 }

Granted this is a somewhat short method, but we have methods which take 6 parameters, and only 2 actual lines of code.  That's 12 lines of code taken up for argument checking, and 2 lines of code.  That would put our crap to code ratio at 6/1.

The Solution

Wouldn't it be much nicer if you could do something like this:

1 public void AddUser([NotNull] Organization org, [NotNull] User user) 2 { 3 org.AddUser(user); 4 _ordDal.Save(org); 5 }

 

PostSharp is almost there to let you write code just like that.  Currently, there is no support for an OnParameterAspectBoundaryAttribute in PostSharp, so we have to do things just slightly differently:

[NotNullHelper] public void AddUser([NotNull] Organization org, [NotNull] User user) { org.AddUser(user); _ordDal.Save(org); }

We have to have a helper class were all the actual code lives.

How PostSharp Works

PostSharp works by weaving all your AOP attributes with your source code after the compiler compiles your code.  This article by Gael Fraiteur describes in more detail how the PostSharp process works.  After the code is post-compiled by PostSharp, you end up with something very ugly that looks like this:

public void AddUser([NotNull] Organization org, [NotNull] User user) { MethodExecutionEventArgs ~laosEventArgs~2; try { object[] ~arguments~1 = new object[] { org, user }; ~laosEventArgs~2 = new MethodExecutionEventArgs(methodof(OrgManager.AddUser, OrgManager), this, ~arguments~1); ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnEntry(~laosEventArgs~2); if (~laosEventArgs~2.FlowBehavior != FlowBehavior.Return) { org.AddUser(user); _orgDal.Save(org); ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnSuccess(~laosEventArgs~2); } } catch (Exception ~exception~0) { ~laosEventArgs~2.Exception = ~exception~0; ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnException(~laosEventArgs~2); switch (~laosEventArgs~2.FlowBehavior) { case FlowBehavior.Continue: case FlowBehavior.Return: return; } throw; } finally { ~PostSharp~Laos~Implementation.NotNullHelperAttribute~3.OnExit(~laosEventArgs~2); } }

I don't know about you, but I would have one HELL of a time trying to debug this, thankfully PostSharp touches up the PDB files, so when your debugging, you only see and debug the source code you've written, both your attribute, and your business logic.

The Drawbacks

PostSharp modifies your code! Well, not directly, but it is still modifying your code (as seen above), but thankfully it touches up the PDB files so all the mess under the hood is hidden from you.

Conclusion

This is but one of the many things you can do with AOP and PostSharp.  Next up, I plan to write some validation attributes.  Look for those in the next few weeks.  In the mean time, download the source code for the NotNullAttribute.

I'm sorry if this post looks terrible in your feed reader, I still haven't been able to figure out why the code looks terrible.  If anyone has any suggestions, let me know.  I'm using DasBlogCE as my blog engine.

kick it on DotNetKicks.com
.NET | AOP | C# | PostSharp
Sunday, November 25, 2007 8:37:23 PM (Alaskan Standard Time, UTC-09:00)
# Sunday, October 07, 2007

If you've read Raymond Chen's blog long enough, then you know trying to change system stuff directly in Windows registry is discouraged, if not frowned upon.  So when I kept hacking away at the registry trying to get some Windows Firewall exceptions for XP and Vista created, I decided to take a step back and see what Windows's API's are out there to do this.

Doing some Google searches doesn't reveal much (which is why I decided to blog this), except these two hidden gems Syslog daemon for Windows Eventlog, and Adding a port to the XP Firewall.  Both of these gave me pointers in the right direction to create this gem:

  1 private static void ExceptionToFirewall(bool add, string imageFileName, string name)
  2 {
  3 	Type netFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr");
  4 	INetFwMgr mgr = (INetFwMgr)Activator.CreateInstance(netFwMgrType);
  5 
  6 	INetFwProfile curProfile = mgr.LocalPolicy.CurrentProfile;
  7 	if (add)
  8 	{
  9 		Type NetFwAuthorizedApplicationType = Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication", false);
 10 		INetFwAuthorizedApplication app = (INetFwAuthorizedApplication)Activator.CreateInstance(NetFwAuthorizedApplicationType);
 11 
 12 		app.Name = name;
 13 		app.ProcessImageFileName = imageFileName;
 14 		app.Enabled = true;
 15 		app.RemoteAddresses = "*";
 16 		app.Scope = NET_FW_SCOPE_.NET_FW_SCOPE_ALL;
 17 
 18 		curProfile.AuthorizedApplications.Add(app);
 19 	}
 20 	else
 21 	{
 22 		curProfile.AuthorizedApplications.Remove(imageFileName);
 23 	}
 24 }
 

To use this, you'll need to add a reference to COM component HNetCfg.FwMgr (Guid "{304CE942-6E39-40D8-943A-B913C40C9CD4}", file path C:\windows\system32\hnetcfg.dll).

One note, don't use the IpVersion property of INetFwAuthorizedApplication, under Windows Vista it throws a NotImplimentedException.

kick it on DotNetKicks.com 

del.icio.us Tags: , ,

C# | Firewall | Windows
Sunday, October 07, 2007 6:50:55 PM (Alaskan Daylight Time, UTC-08:00)
# Thursday, September 13, 2007

Usually I post solutions I've discovered or created to problems I've encountered.  Now, I've run into a problem with the XmlSerializer and I need your help solving it.  Scroll to the bottom for an update.

The Problem

I have a class called Foobar.  Foobar inherits from List<string>, and contains one member Title.  When I use the XmlSerializer to serialize and deserialize Foobar, all the items in the List are make it through safely, but the member Title does not.

The Code

using System; using System.Collections.Generic; using System.IO; using System.Xml.Serialization; internal class Program { private static void Main() { Foobar f = new Foobar(); f.Add("1"); f.Add("2"); f.Title = "Title"; MemoryStream mem = new MemoryStream(); XmlSerializer xs = new XmlSerializer(typeof(Foobar)); xs.Serialize(mem, f); mem.Seek(0, 0); mem.Seek(0, 0); Foobar deser = (Foobar)xs.Deserialize(mem); Console.WriteLine(deser); } } [Serializable] public class Foobar : List<string> { public string Title; }

The Solution

One way I came up with to solve this problem is make Foobar not inherit from List<string>, and make a member called Items that is a List<string>, but that's kind of hokey.  I've searched Google and can't find a solution.  So I'm appealing to my dear readers for a better solution.

Update

Looks like I was being way to specific in my Google search, searching on "XmlSerializer List" gives us this http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&SiteID=1 as the first item.  In the post,

Elena Kharitidi says "XmlSerializer does not serialize any members if a collection. Only collection items get serialized. This is by design, basically a decision was made to handle collections as arrays not as classes with multiple properties, so collections should look like arrays on the wire, therefore they do not have any members other then collection items, and can be “flattened” by adding the [XmlElement] to the member of the ICollection type."

Long and short, I need to use the hokey solution I came up with (or something like it), or write my own serializer.

Thursday, September 13, 2007 7:22:29 AM (Alaskan Daylight Time, UTC-08:00)