Showing posts with label csharp. Show all posts
Showing posts with label csharp. Show all posts

Monday, March 17, 2008

Recursive it is.

Well, for the gtk# presenter injection issue, I determined that I could do the recursive method for in about fifteen lines of code, so I implemented that. I was stumped for quite some time because the recursion wasn't descending at all -- it turns out I was casting widgets to Gtk.Bin when I should have been casting to Gtk.Container.

The code:

public class ViewAttribute : Attribute {}

public class InjectAttribute : Attribute {}

[CastleComponent("bootstrapViews", typeof(BootstrapViews))]
public class BootstrapViews
{
private IWindsorContainer _container;

public BootstrapViews(IWindsorContainer container)
{
_container = container;
}

public void Bootstrap(Widget widget)
{
Container bin = widget as Container;
if (bin == null)
{
return;
}
foreach (Widget child in bin.Children)
{
Bootstrap(child);
}

object[] attrs = bin.GetType().GetCustomAttributes(typeof(ViewAttribute), false);
if (attrs.Length > 0)
{
foreach (FieldInfo field in bin.GetType().GetFields())
{
if (field.GetCustomAttributes(typeof(InjectAttribute), false).Length > 0)
{
field.SetValue(bin, _container.Resolve(field.FieldType));
}
}
}
}
}

Sunday, March 16, 2008

gtksharp and MVP

Switching gears to C#, since, though I love D, I need a working mocks library to write any significant code in it, and dmd bugs prevent dmocks from working correctly.

I'm using gtk#/stetic to create a GUI of moderate complexity, and of course I'm using the Model-View-Presenter pattern. Reminiscent of ASP.NET MVP issues, the main problem is getting a reference to a presenter into a view -- gtk# doesn't use a central object builder that I can hook into; everything happens in a Build method.

So I have three options that I can pursue in achieving a reasonable MVP model:
  1. Each custom widget gets a reference to the Castle container and resolves its presenter that way.
  2. I build my GUI, then do a depth-first traversal of all the components, looking for an attribute set: [View(Type register)] on the class, [Inject] on the presenter(s). Any such classes, I register with the container, then fill in their dependencies. This works for everything that inherits from Gtk.Bin, but I have to copy it for any other gtk classes that my widgets derive from.
  3. Possibly using inheritance, my widgets subclass a SmartPart class and register themselves with a singleton (using the typical singleton pattern) that will register them with the container and fill in dependencies. This means I spend less time at runtime looking at widgets.
Option #1 is not happening.
Option #3, using generics, is reasonably simple, and it works unless I have one view with multiple presenters.
Option #2 is the fully general solution, which I probably won't be implementing. It'd be great, except for the speed, but it's rather yagni.

Of course, the problem with #2 is that my constructors will have to be modified, or the presenters might do something foolish:

public MyWidget()
{
this.Build();
base(whatever);
}
// was:
// public MyWidget() : base(whatever)
// {
// this.Build();
// }

As an aside, has anyone had luck getting CruiseControl.net running on debian?