I love the Reactive Framework, I will get to why in a minute. I even did a talk on it at the Guerrilla.NET class in May. That talk didn’t go so well because they keep changing the freakin’ API! Every single time I upgrade I have to fix things. This last class unfortunately I didn’t even realize that I was upgrading. I made the mistake of creating a project from scratch and using NuGet to pull down the latest version of Reactive. All of the Demo code that I was using broke in subtle ways that I couldn’t quite figure out live, so I had to pull out a project that I had built a week prior. I just now had the time to sift through the changes and make everything work again.

There are still two major ways to subscribe to UI events. The API used to be called FromEvent, now it is FromEventPattern, even though FromEvent still exists for some reason. The important part isn’t whether th API is called FromEvent or FromEventPattern. The distinguishing feature is whether you pass one generic type argument or two. If you just pass one you get access to use the old string method like this:

var mousemoves1 =
	from evt in Observable.FromEventPattern<MouseEventArgs>(rect, "MouseMove")
	select evt.EventArgs.GetPosition(LayoutRoot);

If you pass in two arguments (the first being the delegate type, and the second being the EventArgs type) you get to use the more confusing, but more flexible API. It makes sense after you think about it for a while. That one looks like this:

var mousemoves2 =
	from evt in Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
		h => MouseMove += h, h => MouseMove -= h)
	select evt.EventArgs.GetPosition(LayoutRoot);

The reason you can’t simple pass MouseMove is because the add_ and remove_ methods for the event aren’t exposed directly.

Anyway, one of the best features of Reactive is the fact that you can transform a set of UI specific events that can only be handled by the UI to a set of events that can be handled by anyone, a ViewModel for instance.

var textChanged = Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>(
				h => textBox.TextChanged += h,
				h => textBox.TextChanged -= h);
var stringsChanging = 
	from tc in textChanged
	select ((TextBox)tc.Sender).Text;

// Now that we have transformed these events we can pass 
// them safely into the ViewModel
// which will still know nothing of how they were generated
viewModel.SetupSubscription(stringsChanging);

The idea of transforming an passing around events is one of the main reasons why I still love Reactive even though they break me every month or so…

I just finished a Guerrilla.NET in Boston with Michael Kennedy and Mark Smith. Here are the topics we covered.

  • Introduction to WPF and Silverlight
  • ASP.NET MVC 3.0: Beyond the Basics
  • LINQ to Objects and LINQ to XML
  • Entity Framework
  • Model-View-ViewModel for WPF and Silverlight
  • PFx: Task and The Parallel Class
  • Thread Safety and Concurrent Data Structures
  • Building WCF REST Services
  • C# 3.0, 4.0, and 5.0
  • Entity Framework and the Repository Pattern
  • jQuery
  • Cloud Computing for the .NET Developer: IaaS, PaaS, and Patterns
  • The NoSQL Movement, LINQ, and MongoDB
  • iOS Programming with .NET and MonoTouch
  • Design Patterns for Testability (DI, IoC, and unit testing)
  • Reactive Framework for .NET (Rx)
  • WCF Data Services
  • Power Debugging with WinDBG

I had a great time, and as an added bonus I learned some things. I was monkeying for Mark while he was doing the “Entity Framework and the Repository Pattern”. He did two things that I thought were better than I had done in the past. But first some background…

I used to structure my repositories using an interface similar to this:

IEnumerable<T> GetAll() // or sometimes returning an IList
T GetById(TKey id)  // sometimes just taking an object
void Add(T t)
void Delete(TKey id) // sometimes taking a T
void Save()

I may have other interfaces which specialize a particular IRepository to contain additional query methods.
Sometimes when I am implementing the repository pattern I combine it with a session object. This is especially nice when using NHibernate or doing Web work (where the controller method creates the session and closes it before returning). The session will hang on to the context so that different repositories can be called together in a transaction.

Mark pointed out two things that work differently in Entity Framework and LINQ than in other ORMs.
1) Save() doesn’t need to go on the individual repositories anymore it can be moved up into the Session object. This is because SaveChanges() commits all changes across anything using the same context.
2) If you change the All method to return an IQueryable you can remove all of the other Get methods, because they can be built using LINQ.

So the new IRepository looks like:

IQueryable<T> All
void Add(T t)
void Delete(T t)

That is a good simplification, thanks Mark.

For the G.NET in Boston last week I needed to setup a demo for the WCF 4.0 Announcement and Discovery pieces. After sitting through the Parallel Task library talks I was inspired to try to come up with a way for the client to start trying to discover the service while at the same time the service is trying to announce itself. Whichever one finishes first is the one the client will use. I couldn’t actually get it done before the demo because I ran out of time, but I did manage to get it finished later. So here are the results.

First setup the service with an announcement behavior:

<system.serviceModel>
	<services>
		<service name="GenericService.GenericService"
			behaviorConfiguration="mex">
			<endpoint
				address=""
				binding="basicHttpBinding"
				contract= "Interface.IUniversalContract"/>
			<endpoint name="discoEp"
				kind="udpDiscoveryEndpoint" />
		</service>
	</services>
	<behaviors>
		<serviceBehaviors>
			<behavior name="mex">
				<serviceDiscovery>
					<announcementEndpoints>
						<endpoint kind="udpAnnouncementEndpoint"/>
					</announcementEndpoints>
				</serviceDiscovery>
				<serviceMetadata httpGetEnabled="true"/>
				<serviceDebug includeExceptionDetailInFaults="true"/>
			</behavior>
		</serviceBehaviors>
	</behaviors>
</system.serviceModel>

The tricky part is in the client:

First setup an announcement service so that we can hear when incoming announcement messages arrive.

Here is the field:

static TaskCompletionSource<EndpointAddress> tcsFound;

Here is the code to set it up:

tcsFound = new TaskCompletionSource<EndpointAddress>();

var announceSvc = new AnnouncementService();
announceSvc.OnlineAnnouncementReceived +=
	OnOnlineAnnouncementReceived;
announceSvc.OfflineAnnouncementReceived +=
	OnOfflineAnnouncementReceived;
var announceHost = new ServiceHost(announceSvc);
announceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());
announceHost.Open();

And the delegate which completes the task:

static void OnOfflineAnnouncementReceived(object sender, AnnouncementEventArgs e)
{
	Console.WriteLine("Service is now offline");
}
static void OnOnlineAnnouncementReceived(object sender, AnnouncementEventArgs e)
{
	Console.WriteLine("Service is now online");
	tcsFound.TrySetResult(e.EndpointDiscoveryMetadata.Address);
}

So that it one part. Now the other part is actively going out to find the service.

Here is the field:

static Task<EndpointAddress> findTask;

Here is the code to set it up:

findTask = new Task<EndpointAddress>(() => {
	EndpointAddress localAddress = null;
	do
	{
		localAddress = FindService();
	} while (localAddress == null);
	return localAddress;
});

And lastly the method to actually find the service…

private static EndpointAddress FindService()
{
	var discoProxy = new DiscoveryClient(new UdpDiscoveryEndpoint());
  	var fc = new FindCriteria(typeof(IUniversalContract));
  	FindResponse fr = discoProxy.Find(fc);
	discoProxy.Close();
  	int count = fr.Endpoints.Count;
	foreach (EndpointDiscoveryMetadata item in fr.Endpoints)
	{
		Console.WriteLine(item.Address);
	}
  	if (count > 0)
		return fr.Endpoints[random.Next() % count].Address;
	return null;
}

With those two pieces in play the only thing left is to call the service when either of the tasks completes first.

var tasks = new Task<EndpointAddress>[] { findTask, tcsFound.Task };
int index = Task.WaitAny(tasks);
EndpointAddress address = tasks[index].Result;
InvokeService(address);

I will leave the implementation of InvokeService up to the reader, but the rest of it is done – pretty sweet!

This week I was called on to do a very strange on-site custom course. They basically couldn’t decide on any one topic so they wanted me to talk a little bit about everything, mainly concentrating on:

  1. Advanced Windows Forms
  2. Windows Communication Foundation
  3. Unit Testing

As I have covered Windows Communication Foundation many times, and I didn’t have quite enough time to do unit testing any justice, the most interesting of the talks (I thought) was Windows Forms. We covered MDI, Notify Icons, and to my surprise had an interesting eventing discussion. Someone had asked about the difference between WPF and Windows Forms. I was trying to describe how they can be very similar but if you program WPF the right way how very different they really were and how complicated WPF was compared to Windows Forms. As part of this description I mentioned that Windows Forms has only the direct event model, but WPF has both bubbling and tunneling in addition to the direct model. Again someone raised their hand and asked if there was no way to simulate the bubbling model that they had in MFC (and WPF) using Windows Forms. He mentioned that they were having problems with coupling between components. I told them that the Client Application Block had something like this built in. He said that they found the CAB a little too heavy, and I agreed. I told him I would think more about it and get back to him tomorrow.

When I got back to the hotel that evening I started thinking about it and realized that there was a way to simulate it using a publish and subscribe type mechanism. This is basically a lightweight version of what the CAB clock does. I named my class the same as theirs as a form of flattery.

When you specify that you want to subscribe to a button click using the following syntax.

EventBroker.Instance.Subscribe(this, typeof(Button), "Click", OnButtonClick);

The EventBroker basically just walks the tree of controls recursively searching for controls of the type button, and then adds itself as a subscriber to that button. If someone else in the hierarchy also subscribes for button clicks the EventBroker knows which subscriber to call first. If the inner subscriber handles the event then the outer subscriber never sees the event, just like bubbling.

Best of all, you only need to drop in this one file, and away you go.
Here is the file in its entirety:

using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;

namespace WindowsFormsApp
{
	// helper method to make the code below more readable
	public static class ControlExtensions
	{
		public static bool IsParentOf(this Control c, Control other)
		{
			Control parent = other;
			while (parent != null)
			{
				if (c == parent)
					return true;
				parent = parent.Parent;
			}
			return false;
		}

	}

	public class EventBroker
	{
		class EventHolder
		{
			public Control Control { get; set; }
			public EventHandler<BubblingEventArgs> EventHandler { get; set; }
		}

		// singleton
		public static readonly EventBroker Instance = new EventBroker();

		readonly Dictionary<Control, List<EventHolder>> subscribers = new Dictionary<Control, List<EventHolder>>();

		public void Subscribe(Control c, Type type, string eventName, EventHandler<BubblingEventArgs> callback)
		{
			SubscribeRecursive(c, c, type, eventName, callback);
		}

		private void SubscribeRecursive(Control subscriber, Control c, Type type, string eventName, EventHandler<BubblingEventArgs> callback)
		{
			if (type.IsInstanceOfType(c))
			{
				// check to see if this eventName exists and subscribe
				Debug.WriteLine(string.Format("{0} is of type {1}", c.Name, type.Name));

				List<EventHolder> list;
				var newHolder = new EventHolder
				{
					Control = subscriber,
					EventHandler = callback,
				};

				// do we already have a subscriber for this object?
				if (subscribers.TryGetValue(c, out list))
				{
					// walk through the list trying to find where to insert this subscriber
					bool inserted = false;
					for (int cnt = 0; cnt < list.Count; cnt++)
					{
						EventHolder holder = list[cnt];

						// uses the extension method above
						if (holder.Control.IsParentOf(subscriber))
						{
							list.Insert(cnt, newHolder);
							inserted = true;
							break;
						}
					}
					// if they weren't inserted add them at the end
					if (!inserted)
					{
						list.Add(newHolder);
					}
				}
				else
				{
					// this is a new object, subscribe to its event
					EventInfo eventInfo = c.GetType().GetEvent(eventName);
					eventInfo.AddEventHandler(c, new EventHandler(OnEvent));

					// then create a new list of subscribers keyed to this object
					list = new List<EventHolder> {newHolder};
					subscribers.Add(c, list);
				}
			}

			// now recursively subscribe
			foreach (Control child in c.Controls)
			{
				SubscribeRecursive(subscriber, child, type, eventName, callback);
			}
		}

		public void OnEvent(object sender, EventArgs e)
		{
			// grab the list of subscribers for this control
			List<EventHolder> list = subscribers[(Control)sender];

			foreach (EventHolder holder in list)
			{
				Debug.WriteLine(string.Format("About to call {0}", holder.Control.Name));

				// call this subscriber
				var handledArgs = new BubblingEventArgs {InnerArgs = e};
				holder.EventHandler(sender, handledArgs);

				// if they handled the event don't propogate further
				if (handledArgs.Handled)
					break;
			}
		}
	}
}

[Update: this refers to the 1.0 version found in .NET 3.5]

Sure, I had read the disclaimer here: http://efvote.wufoo.com/forms/ado-net-entity-framework-vote-of-no-confidence/

But these were the requirements:

  • Needed to support multiple databases
    They had already switched databases once (from Oracle to SQL Server) and they still had some other databases in Oracle
  • Could not use strings (had to be type-safe)
    This was due to the amount of change (we were developing a fairly complicated v1.0 product)

When we initially started the project back in early 2008 (a year or so ago) we had a meeting with four people to try and choose an ORM. The first decision made was we agreed that NHibernate was out, because it uses strings in its query syntax, and the support for generation isn’t on par with the others. We discussed many aspects as to how the remaining choices are used. One of the most important points was whether they had a good online community, but all of them met that bar. Here is a summary of the differences:

Consideration Linq to SQL Entity Spaces Entity Framework
Released Product Yes Yes No
Supports LINQ Yes No Yes
Clean business objects Yes No Yes
Easy query navigability for Many-to-manys No Yes Yes
Easy to modify Many-to-manys No No Yes
Supports all databases No Yes Yes

Ultimately it was decided that as long as we are careful it should be easy to convert between the DALs. That way we can start of in one and move to another one. We will start off with Entity Spaces. One additional action item was to check out LLBLGen Pro, and msbuild support for MyGeneration.

Now that 3.5 SP1 had finally shipped we decided to completely replace our data access layer with Entity framework. One thing that we didn’t like going in was the fact that we still wouldn’t be able to replace our existing two-tiered entity objects. In our initial model we have one set tied to Entity Spaces and the other which is a DTO representing basically the same object.

What we liked:

  1. We could use LINQ
    I know that it doesn’t seem like this is such a big deal, but check this out:

    Before:

    public static ContainerInfo[] GetContainerInfosByExternalId(
    	string externalSampleId)
    {
        var containerInfos = new List<containerinfo>();
        if (String.IsNullOrEmpty(externalSampleId))
            return new ContainerInfo[0];
        var sampleSlotQuery = new SampleSlotQuery("s");
        Dal.InitConnectionName(sampleSlotQuery.es);
        var containers = new ContainerCollection();
        containers.Query.es.JoinAlias = "c";
        Dal.InitConnectionName(containers.es);
    
        containers.Query.InnerJoin(sampleSlotQuery)
           .On(containers.Query.ContainerId == sampleSlotQuery.ContainerId);
        containers.Query.Where(sampleSlotQuery.ExternalSampleId == externalSampleId);
        containers.Query.OrderBy(containers.Query.ContainerId.Ascending);
        if (containers.Query.Load())
        {
            foreach (Container container in containers)
            {
                containerInfos.Add(ConvertToContainerInfo(container));
            }
        }
        return containerInfos.ToArray();
    }
    

    After:

    public static ContainerInfo[] GetContainerInfosByExternalId(
    	WorkflowStateEntities db, string externalId)
    {
        return
            (from c in db.Containers.Include("Samples")
             from ss in c.SampleSlots
             where ss.ExternalId == externalId
             select ConvertToContainerInfo(c)).ToArray();
    }
    

What we didn’t like. These were relatively minor things like:

  • No lazy loading
  • Non type-safe eager loading
  • (See here)

It took 5 of us about 4 days to convert the entire thing over. After it was done I tried to figure out how many lines we were able to remove. However, there was a problem, because even though I knew we were able to reduce the code, the Code Metrics in Visual Studio showed that the number of lines increased. After some frustration, I finally used a version of wc (the Unix utility) which showed a 10-15% reduction across the board

Another problem we had was the varchar / nvarchar problem. We actually reported this problem to the Entity Framework team through one of our Help support tickets. From one of our developers
In EF, as it turns out, the queries are ALWAYS cast to nvarchar (Unicode) regardless of the schema column type being a varchar (or bit). Before running my last set of traces (those shown above), I made sure that ALL columns in the schema were preset to be nvarchar types before running the EF code. That actually improved the query speed, cutting the time in half from about 4000 microseconds to 2200 microseconds

But the biggest problem turned out to be performance. We had some pretty big load operations going in. By converting one of these queries went from 21 seconds in Entity Spaces to 2 minutes in Entity Framework. Basically a 6x factor across the board. This performance was not acceptable for our product. So after doing all of the conversion we had to roll everything back – uggh!

I was working with a client that wanted to be able to layout the screen using some pretty complicated but fixed layouts. All of these needed to be able to be adjusted by the client after they were shown, so they needed to use splitters. To help them to be able to produce these layouts easily I created a control. It allows them to simply set the number of reports and the layout type, and assign the reports to the various panels. To demonstrate what the result looks like and show how to programmatically use the control I created a little test project. Here is a screen shot of the result.

Unfortunately it looks a little bit like an eye chart ;) . However, the cool thing is that all of the splitters shown in the screen capture actually work. In fact if you look I adjusted some on the second row. There is another test that I did where it cycles through all the splitters one at a time. The project is included here.

That’s it. The third time you get asked about a particular topic, its time to stop making it up as you go along, and actually write something down. I was asked (again) today by another one of my clients about Validation within Windows Forms. So I am going to take some time to write up my thoughts

First let me say that there are several parts to validation. There is simple user input or "control" validation, displaying of the results of a failed validation, and then the complex business rule or "form" validation. Lets deal with each in turn

Simple user input validation

As you probably know each control in a form contains a Validating and a Validated event. In order to get those events to fire the CausesValidation property on the control needs to be true, but since that is the default, no problems there. Most people start off by using Validating to implement some simple validation rules like making sure that the input is in the proper form. ASP.NET provides the following forms of validation:

  • RequiredFieldValidator – Make some input has been chosen for the control
  • RangeValidator – Make sure the input is within a specific range
  • RegularExpressionValidator – Make sure the input looks like a regular expression
  • CompareValidator – Make sure that the input in one control "matches" the input in another
  • CustomValidator – Check the input as you see fit

Windows Forms does not provide those controls out of the box. However, there are solutions, as we will see shortly.

There are two basic approaches to validating many controls on a Form. The first is the ASP.NET approach where one or more validators are dragged onto the form for *each* control that needs validation. The second is to use an IExtenderProvider (tooltips and errorProviders are examples of ExtenderProviders). The idea behind a ExtenderProvider is that you drag one component onto the form, and it extends the properties for every control on that form.

Michael Weinhardt wrote an article providing the ASP.NET way. The model was described in a 3 part article as well as the accompanying source code. In the article just look at the first part as 2 and 3 have been obsoleted by newer versions of .NET (2.0).

Billy Hollis wrote an article providing the second way which has since been removed from MSDN. However the WebCast is still around, and the source code can still be downloaded.

The choice between the two models essentially comes down to the percentage of controls needing validation on a given page. If the percentage is large, go with Billy Hollis’ model, if the percentage is small go with Michael Weinhardt’s model. Another reason for going with Weinhardt is if you are building both Forms and ASP.NET applications in order to stay consistent. BTW – I prefer Billy Hollis’s model. His code is in VB.NET, but I ported it to C#.

Displaying errors

Most everyone agrees that the ErrorProvider is the right way to signal errors in Windows Forms. However some people feel that novice users won’t be able to tell what the error actually is. If your application is meant to be used by novices there are two approaches.
a) build a little framework that dynamically creates an error label with each control that is being checked
b) provide a ValidationSummary control ala ASP.NET that contains all of the errors
I prefer the second option here. Note the Weinhardt’s article mentioned above provides a Validation form which pops up a modal dialog containing the error information, which is another way to go. I dislike modal popups, but I recognize that as largely a matter of taste.

Form and complex business rule validation

Examples of this are the CompareValidator that I mentioned earlier. But here is where the Validating event can really shine. Typically you hook this event and the call into some business logic which tests sums of values, or certain strings when an enum has been chosen above, things like that. The same Validation summary can then be used to display the results of such validation.

Happy Validating!

Which is easier? Bringing someone up to speed on the .NET platform or bringing someone up to speed on your business? This is the question that project managers should be asking themselves when converting an old project such as MFC or C++/COM to .NET.

This is not the first release for .NET. Indeed it has been released for five years already (not even counting the large Beta period). The number of assemblies and types to learn is enormous. That is a lot of knowledge to absorb. In fact the longer companies wait to go to .NET, the more learning they have to do.

The productivity gains from .NET are significant, but think of all that time spent just getting back to the level of competency where you are right now. When starting on a major refactoring of the current product, it makes more sense to keep only those developers who have a ton of accumulated business knowledge. Then hire a bunch of expert .NET developers and do a lot of paired programming to get the knowledge to transfer between the groups.

I love Reflector, but sometimes I want to be able to explore through the Framework in more interesting ways. In this post I am going to use the program that I created last time to do some exploring.

How many types are there in the 2.0 version of the framework? Just click Go:
15834 – Wow! [Update: After 3.5 SP1 - 16375]

How many instances of the Async pattern are there in the .NET Framework? There are a bunch of ways to do this one. One way was shown in the picture last time.
Select Method, type ^Begin, press Add, select ParameterType, type AsyncCallback, press And, and click Go
831 [Update: 857]  The Name textbox uses regular expressions so the caret (^) before the word Begin just means that it should only match methods that start with Begin, rather than anywhere in the name (which is the default).

Looking through those it seems that lots of those are the possibly CPU bound delegate BeginInvoke pattern. Let’s filter out the delegates Leaving the expression the way it was last time add:
Select Inherits, type Delegate, check Not (checkbox), press And, and click Go:
233 [Update: 247]
So I guess that means there are about 600 delegates? I will double check that in one second.

First it looks like a lot of the instances of the async pattern that are left inherit from Stream, lets filter those out as well. Again leaving the expression the way it is:
Select Inherits, type Stream, check Not (checkbox), press And, and click Go:
68 [Update: 76] and one of those is Stream itself. Go ahead and have a look – the ones left have a lot of diversity: SqlCommand, LdapConnection, Dns lookup, WebRequest, HttpListener, tons of Socket stuff, MSMQ, .NET Remoting, System.Transactions, and HttpAsyncHandler. All provided for you free of charge in the .NET framework itself.

Now lets go back to those delegates:
Press Clear, select Inherits, type Delegate, and click Go:
595 [Update: 607] – close enough that I believe it :)

Another question that I wanted answered was what are the generic delegates? Leaving the expression the way it is:
Select Type, type `(backtick), and click Go. The backtick is the way that generic types are represented in the IL. Here we see a really small list, but all of them are extremely useful: Action ,Predicate, Comparison, Converter, etc.

UsingReflectForEntities

I played around a little more and found lots of other oddities. For example: I was searching for Trees and I found an RBTree in the System.Data assembly – WTF? I have attached the finished project – happy hunting!

Now that I teach the Essential .NET class for DevelopMentor, I find myself scouring the MSDN reference documentation looking for specific types. After doing this for an hour or so, I got to thinking – there has to be a better way. So I started out with a fairly simple application which used reflection and a simple string.Contains to browse for certain classes in the framework. Because of the naming convention of ending the class name with the name of the class you are inheriting from this worked quite nicely.

The form looked like this:

ReflectForEntities1

However, I soon needed more features like:

  • looking for certain methods
  • being able to delete items from the tree manually, when I found they didn’t apply
  • displaying the count of elements found at any location

So I kept adding functionality.

Then I needed the ability to combine multiple filters at one time, like looking for Asynchronous Programming Model (APM) methods. This is where things got interesting. To do this I created a set of filters. A filter is really just class that stores some information and contains boolean function that acts upon a type to figure out if it should be included in the result set. I created in interface for this purpose which looked like this:

interface IFilter
{
	bool IsTypeAllowed(Type t);
}

The implementation of this interface is pretty easy. Basically checking each the name of each type against a set of regular expressions

public bool IsTypeAllowed(Type t)
{
	if ((Type & TypeSearchType.Namespace) != 0)
	{
		if (t.Namespace == null) return false;
		if (!Regex.Match(t.Namespace).Success)
			return false;
	}
	if ((Type & TypeSearchType.Type) != 0)
	{
		if (!Regex.Match(t.Name).Success)
			return false;
	}
	if ((Type & TypeSearchType.Member) != 0)
	{
		found = false;
		foreach (MemberInfo mi in t.GetMembers())
		{
			if (Regex.Match(mi.Name).Success)
				found = true;
		}
		if (!found) return false;
	}
	return true;
}

This too worked really well until I needed to filter out methods. I needed a way of returning a subset of the methods on the type which met the filter criteria. To accomplish this I had to hackmodify the interface to look like this:

interface IFilter
{
	bool IsTypeAllowed(Type t, out List<MemberInfo> mis);
}

Then I had to modify the behavior to look like this (I added inheritance checking and parameter type checking while I was in there poking around)

public bool IsTypeAllowed(Type t, out List<MemberInfo> mis)
{
	mis = null;
	if (filterNullNamespaces && t.Namespace == null) return false;

	if ((Type & TypeSearchType.Inherits) != 0)
	{
		if (!IsBaseTypeAllowed(t))
			return false;
	}
	if ((Type & TypeSearchType.Namespace) != 0)
	{
		if (!Regex.Match(t.Namespace).Success)
			return false;
	}
	if ((Type & TypeSearchType.Type) != 0)
	{
		if (!Regex.Match(t.Name).Success)
			return false;
	}
	if ((Type & TypeSearchType.Member) != 0)
	{
		if (!IsMemberAllowed(t, out mis))
			return false;
	}
	return true;
}

bool IsBaseTypeAllowed(Type t)
{
	bool foundType = false;
	while (t.BaseType != null)
	{
		t = t.BaseType;
		if (Regex.Match(t.Name).Success)
		{
			foundType = true;
			break;
		}
	}
	return foundType;
}

bool IsMemberAllowed(Type t, out List<MemberInfo> mis)
{
	mis = null;
	bool foundType = false;
	foreach (MemberInfo mi in t.GetMembers())
	{
		bool foundMethod = false;
		if (((mi.MemberType & (MemberTypes.Constructor | MemberTypes.Method)) != 0) &&
			(Type == TypeSearchType.ParameterType))
		{
			MethodBase mb = (MethodBase)mi;
			foreach (ParameterInfo pi in mb.GetParameters())
			{
				if (Regex.Match(pi.ParameterType.Name).Success)
				{
					foundMethod = true;
					break;
				}
			}
		}
		else
		{
			foundMethod = Regex.Match(mi.Name).Success;
		}

		if (foundMethod)
		{
			if (mis == null)
				mis = new List<MemberInfo>();
			mis.Add(mi);
			foundMethod = false;
			foundType = true;
		}
	}
	return foundType;
}

Then on to the boolean logic piece. There are essentially 3 binary operators (that I cared about): NOT, AND, and OR. NOT is a unary operator, whereas both AND and OR are binary. I chose to create three new classes that contain the simple Filter that I had created earlier. The benefit of containing rather than inheriting/overriding is that I was able to encapsulate all of the logic in one and only one place.

The other problem was that regardless of how complicated the final expression was I wanted to be able to perform a NOT on it to produce the sets complement. To do that I had to Add another method on the interface so that all filter types could produce a NOT. The result of all that refactoring looked like this:

	class NotFilter : IFilter
	{
		IFilter subFilter;

		public NotFilter(IFilter subFilter)
		{
			this.subFilter = subFilter;
		}

		public IFilter CreateNot()
		{
			return subFilter;
		}

		public bool IsTypeAllowed(Type t, out List<MemberInfo> mis)
		{
			mis = null;
			List<MemberInfo> subMis;
			bool subAllowed = subFilter.IsTypeAllowed(t, out subMis);
			if (subMis != null)
			{
				mis = new List<MemberInfo>();
				foreach (MemberInfo mi in t.GetMembers())
				{
					if (!subMis.Contains(mi))
						mis.Add(mi);
				}
			}
			return !subAllowed;
		}

		public override string ToString()
		{
			return "!" + subFilter.ToString();
		}
	}

	class AndFilter : IFilter
	{
		IFilter sub1;
		IFilter sub2;
		public AndFilter(IFilter sub1, IFilter sub2)
		{
			this.sub1 = sub1;
			this.sub2 = sub2;
		}

		public IFilter CreateNot()
		{
			return new OrFilter(sub1.CreateNot(), sub2.CreateNot());
		}

		public bool IsTypeAllowed(Type t, out List<MemberInfo> mis)
		{
			mis = null;
			List<MemberInfo> mis1;
			List<MemberInfo> mis2 = null;
			bool allowed =
				sub1.IsTypeAllowed(t, out mis1) &&
				sub2.IsTypeAllowed(t, out mis2);
			if (allowed)
			{
				if (mis1 != null)
					mis = mis1;
				if ((mis == null) && (mis2 != null))
					mis = mis2;

				if ((mis1 != null) && (mis2 != null))
				{
					mis = new List<MemberInfo>();
					foreach (MemberInfo mi in mis2)
					{
						if (mis1.Contains(mi))
							mis.Add(mi);
					}
				}
			}
			return allowed;
		}
		public override string ToString()
		{
			return string.Format("({0}) && ({1})", sub1.ToString(), sub2.ToString());
		}
	}

	class OrFilter : IFilter
	{
		IFilter sub1;
		IFilter sub2;
		public OrFilter(IFilter sub1, IFilter sub2)
		{
			this.sub1 = sub1;
			this.sub2 = sub2;
		}

		public IFilter CreateNot()
		{
			return new AndFilter(sub1.CreateNot(), sub2.CreateNot());
		}

		public bool IsTypeAllowed(Type t, out List<MemberInfo> mis)
		{
			mis = null;
			List<MemberInfo> mis1 = null;
			List<MemberInfo> mis2 = null;
			bool allowed1 = sub1.IsTypeAllowed(t, out mis1);
			bool allowed2 = sub2.IsTypeAllowed(t, out mis2);
			bool allowed = allowed1 || allowed2;
			if (allowed)
			{
				if (mis1 != null)
					mis = mis1;
				if ((mis == null) && (mis2 != null))
					mis = mis2;

				if ((mis1 != null) && (mis2 != null))
				{
					foreach (MemberInfo mi in mis2)
					{
						if (!mis.Contains(mi))
							mis.Add(mi);
					}
				}
			}
			return allowed;
		}
		public override string ToString()
		{
			return string.Format("({0}) || ({1})", sub1.ToString(), sub2.ToString());
		}
	}

I also had to refactor the UI a little bit. The form now looks like this:

ReflectForEntities2

Notice that I got a little bit carried away and placed a Flags button on the UI (initially disabled).

There was one caveat. If you were to give me any random boolean expression, I wouldn’t necessarily be able to express it in the program. Expressed in tree form, my program could only produce expressions that looked like:

ExpressionTree1

However, the program was working great; I had no major flaws in the design (that I could see), and I was able to perform some pretty nifty expressions which I will discuss in another blog entry.