Journal of a software dev

August 8, 2009

Adding Controls to a Server Control

Filed under: asp.net, c#, code example — Tags: , — Michael Cromwell @ 10:54 am

Usually looks like this:

var row = new TableRow();
var cell = new TableCell()
    {
         Height = Unit.Pixel(30)
    });
cell.Controls.Add( new Button()
    {
        Text = "Go",
        CommandName = "Go",
        ID = "btnGo"
    });
row.Controls.Add(cell);

How about this instead:

var row = new TableRow();
var cell = row.AppendControl<TableCell>(x =>
                  {
                      x.Height = Unit.Pixel(30);
                   });
cell.AppendControl<Button>(x =>
    {
        x.Text = "Go";
        x.CommandName = "Go";
        x.ID = "btnGo";
    });
 

Implemented with this:

public static ControlExtensions
{
    public static TControl AppendControl<TControl>(this TControl control, Action<tcontrol> initialization)
        where TControl : Control, new()
    {
        var controlToAppend = Activator.CreateInstance<TControl>();
        intialization(controlToAppend);
        control.Controls.Add(controlToAppend);
        return controlToAppend;
    }
} 

I think this reads better especially if you end up appending lots of child controls, thoughts or any other solutions?

April 7, 2009

Using Windsor for Controller Creation in ASP.NET MVC

Filed under: Castle Windsor, asp.net, asp.net mvc — Tags: , — Michael Cromwell @ 8:10 pm

Given it’s reached v1.0 I finally decided to do some work with the ASP.NET MVC framework and what better way than to take the Issue Tracker which currently runs on Rhino Igloo and refactor it to run on ASP.NET MVC, so expect the next few posts to be related to my findings of how to get things done with it.

First thing is that Rhino Igloo out of the box handles controller creation and uses Castle Windsor to do this ASP.NET MVC by default will use it’s own controller builder, because of this it expects your controllers to have a default no-arg constructor this is no good as I have controllers that need their dependencies passed in, so we need to replace the default controller builder with a version that we can hook up to Castle Windsor.

Now I could go and write my own version this is because the framework is very flexible and was built to allow you to plugin your own  objects, in this case an object that implements IControllerFactory will suffice however why re-invent the wheel when the guy’s over at MvcContrib have done most of the work for us.

Getting the MvcContrib Objects

Head over to to the MvcContrib project on codeplex and grab the extras release, now copy the MvcContrib.dll and MvcContrib.Castle.dll into your external references folder and add a reference where you will be doing the app startup.

Setting the Controller Factory

Inside your global.asax or wherever you do app startup you need to add the following code:

ControllerBuilder.Current.SetControllerFactory(
                new WindsorControllerFactory(this.Container));

Notice that I’m passing the current instance of the windsor container which I get for free because I’m using the UnitOfWorkApplication base class from Rhino.Commons, you will probably have some custom way of managing your container, in which case it just needs to be passed in to the constructor of WindsorControllerFactory.

Wiring up the Controllers

Next we need to make Windsor aware of the controllers, I use Binsor for my Windsor configuration this gives me a nice way to autowire new controllers to Windsor without making any changes:

for type in AllTypes("IssueTracker.Controllers"):
    continue unless typeof(IController).IsAssignableFrom(type)
    component type.Name, type:
        @lifestyle="transient"

Gotta love the conditional expression support Boo has to offer it almost reads like a sentence :) You could also use the XML configuration or programmatic configuration to configure your controllers, and that’s all there is to it!

Kudos to the ASP.NET team for having the foresight to allow these kind of extensions to be plugged in so easily and also to the MvcContrib contributer’s for creating this and support for other IoC containers out there.

January 24, 2009

Gridview binded to LinqDataSource not showing association values

Filed under: asp.net — Tags: , , , — Michael Cromwell @ 11:07 am

I’m working on a report screen for IssueTracker.NET and because this is going to be used purely for reporting on data this is a perfect match for leveraging the GridView & a LinqDataSource  to bind to, this will then give me dynamic filtering and paging out of the box splendid!

However after I had added the GridView & LinqDataSource wired the all up and ran the page there was a problem in that my association objects weren’t being displayed, hmm.. so I had code that looked like this:

<asp:TemplateField HeaderText="Assigned To">
    <ItemTemplate>
        <%#Eval("User.Username") %>
    </ItemTemplate>
</asp:TemplateField>

Where User is a property on the current binded object my association object, so I went and re-checked the Linq to Sql generated code and sure enough the User property existed and was ok, so I re-ran with the debugger for the line above the Eval("User") returned null… then it struck me Lazy Loading perhaps the Eval method under the hood may not trigger a lazy loaded property to be retrieved (and in which case we don’t want lazy loading on this property anyway to cut down on DB trips).

So after some looking around it turns out you can control creating and assigning the DbContext object to the GridView via the ContextCreating event, so I subscribed to this and added the following:

protected void IssuesDataSource_ContextCreating(object sender, LinqDataSourceContextEventArgs e)
{
    var db = new IssueTrackerDbContextDataContext();
    db.ObjectTrackingEnabled = false;
    var loadOptions = new DataLoadOptions();
    loadOptions.LoadWith<Issue>(x => x.User);
    db.LoadOptions = loadOptions;
    e.ObjectInstance = db;
}

Here is where you create your own custom DbContext object and set it how you want it, the important part for the above was the definition of the LoadOptions, don’t forget to assign it to the GridView via the e.ObjectInstance property.

Once I had this in place I did a re-run and I had my value displayed, so hopefully this will help people in the same boat.

January 22, 2009

Spaghetti code? No I dont think so

Filed under: asp.net, code example — Tags: — Michael Cromwell @ 9:35 pm

I just wrote this while working on the IssueTracker.NET project:

<%foreach (var comment in issueBeingViewed.AssignedComments)
  { %>
<tr>
<th>
       <%=comment.CreatedAt %> - <%=comment.CreatedBy.Username %></th>
</tr>
<tr>
<td>
       <%=comment.Text %></td>
</tr>
<% }%>

Now some will look at this and be thinking eurgh!… why is he writing classic ASP style spaghetti code and that’s the point, since when did writing code in the page == spaghetti code? I believe that spaghetti code originated because of the shortcomings of ASP 3.0 not allowing us to separate UI concerns from other concerns, but we don’t have this problem in ASP.NET we can quite nicely have our seperate objects in other layers deal with persistence, domain etc… and the code on our pages can deal just with what they are supposed to the UI.

This is why when I look at the code above I don’t think eurgh! because it’s not dealing with anything other than concerns of the UI and in the case above displaying any comments assigned  to the current issue and in my opinion it reads quite well.

January 10, 2009

Finding Web Controls by Type

Filed under: asp.net, code example — Tags: , , — Michael Cromwell @ 7:50 pm

If someone runs into the same problem I was having which was trying to find controls of a certain type they can use this extension method which extends the Control object:

public static class ControlExtensions
{
    public static ICollection<T> FindControlsByType<T>(this Control control)
        where T : Control
    {
        var coll = new List<T>();
        if (control == null) return coll;

        FindControlsByType(control.Controls, coll);
        return coll;
    }

    private static void FindControlsByType<T>(ControlCollection controls, ICollection<T> coll)
        where T : Control
    {
        foreach (Control current in controls)
        {
            if (current.HasControls())
                FindControlsByType<T>(current.Controls, coll);

            if (current is T)
                coll.Add(current as T);
        }
    }
}

Remember as with all extension methods if you are using them in an inherited class you will need to put this before the name of the method otherwise it won’t be seen in intellisense.

December 18, 2008

ASP.NET Ajax weirdness

Filed under: ajax, asp.net — Tags: , — Michael Cromwell @ 9:01 pm

I just ran into a strange issue when trying to serialize one of my objects over a webservice that’s called using Ajax, the weirdness isn’t what you need to resolve the issue but instead how it manifests itself in such a convoluted way and goes like this:

public class Foo
{
    public Foo(Bar bar)
    {
    }

    // some properties here...
}

Say I have the above class and then the following in my webservice:

[WebMethod]
[GenerateScriptType(typeof(Foo))]
public Foo RetrieveFoo(int id)
{
// perform retrival here...
}

Now if I have some javascript on the client that tries to make a call to this webservice it will fail because the javascript proxy to the webservice just doesn’t get created so it ends up being null, this is not good cos’ if you have been making various changes you have no way of knowing why the proxy class isn’t being generated so you have to spend time tracking down what could be causing the issue.

Turns out it’s because my Foo class needs to have a public empty constructor but it took a while to track this down, couldn’t a better way of alerting the issue to the developer been accomplished.

December 13, 2008

Using Rhino Igloo

Filed under: asp.net — Tags: — Michael Cromwell @ 11:11 am

You have probably never heard of Rhino Igloo it wouldn’t surprise me my knowledge of it was born out of curiosity while browsing the Rhino svn trunk. What Rhino Igloo is I would describe as an in the middle framework for web applications with web forms on one side and a full MVC solution (ASP.NET MVC, Monorail) on the other.

Why would i use this instead of webforms…

…the answer lies in why we have MVC frameworks in the first place… Separation of Concerns Rhino Igloo makes it easy to do the right thing and by that I mean structuring your web app so that your View (this includes Code Behind as that class inherits from Page!) is not responsible for everything, only in presention concerns.

Why would i use this instead of a full MVC framework…

…easy you wouldn’t, Ayende makes it very clear that if you can go down the MVC route then do so this framework was built out of a constraint having to use webforms so if this constraint is not present go and use a full MVC framework.

What makes it useful

Opinionated

This framework has strong opinons about how things should be structured and this good as it allows it to make decisions itself which leaves us to concentrate on getting business concerns instead of plumbing.

Let me give you and example, in Rhino Igloo IoC is built in out of the box, it uses Castle Windsor to accomplish IoC so given you have configured Castle Windsor (Binsor is great for this!) your dependencies will be in place at the time a request is made, so if you have a controller class with a dependency on an IRepository<Foo> this will be set for you without any code.

And another, Rhino Igloo gives you base classes to inherit from to plug the IoC into, most notable are BasePage & BaseController (there are others that map to other view artifacts such as BaseControl, BaseWebService) one of the other opinions is that given that you have a page that has a public set property of a class that inherits from BaseController it will be automatically injected via the Rhino Igloo Facility.

Communication between layers

In Rhino Igloo there is a Scope object this object is what makes the layers communicate with each other easier it holds data from the Request either from session, querystring, form values etc… this means that your controller can use this object to quickly get at data sent through. The scope object also allows error details to be set that the view can use to display.

Easier unit testing

Because you have Separation of Concerns testing is made easier, and as an added bonus there is a IContext that is used instead of the HttpContext directly this means you can use the provided FakeContext to aid unit testing.

Binding attributes

One really neat feature Rhino Igloo provides is attributes to enable binding to data provided in the Scope object this inludes the [Inject] and [InjectEntity] attributes, the first one will automatically set the value of a property to what is stored in the Scope object for instance:

// in view
<asp:TextArea ID="SomeValue" runat="server"></asp:TextArea>

// in controller
[Inject]
public property SomeValue
{
    set {someValue = value;}
}

Assuming that I set the text in SomeValue textbox to ‘Foo’ this would now be placed in the someValue field in controller, also note that these attributes can deal with the is mangling that asp.net does for master pages.

But that’s nothing let’s say we have an edit screen for an entity say Project:

// in view: various inputs

// in controller
[InjectEntity(Name="id")]
public property Project
{
    set {project = value;}
}

Now what this will do is take the “id” from the scope object (you can also specify if the value is in session instead) and then make a call to Castle ActiveRecord to retrieve the entity from the database matching the id provided in the Name property, now that is very neat (eager load can also be set).

How to structure

You would usually end up with 3 projects:

  1. A standard ASP.NET web application or website to contain the screens, presentation logic and other presentation concerns
  2. A Controller class library which would house your controllers that would perform orchestration between the Model objects it would probably contain your Repositories if your using that pattern instead of Active Record.
  3. A Model class library which would contain your domain objects, Rhino Igloo makes a lot of user of Castle ActiveRecord so they should be decorated as ActiveRecord classes.

 A note about Castle ActiveRecord

Some may be put off by the use of Castle Active Record as you would suspect that your domain objects would be not testable I can assure that this isn’t the case this framework has been designed in such a way that you can new up an object without having to supply persistence knowledge (connection strings, db connections, config etc…) so you can test your objects as you would normally.

What your then going to say is “ok, so I can test the domain classes but how can I test retrieving, saving, udpating etc… as these are static methods on the domain objects” this is a valid point and here is how I have dealt with it, I use a hybrid approach:

My domain objects inherit from the ActiveRecordBase<> my own entity base class and have there mappings applied via attributes, my controllers use the Rhino Commons IRepository <> classes for persistence this enables me to mock out the repositories and allow easy unit testing.

Summary

I really like this framework it’s like webforms on steroids, it’s value lies in it’s ability to deal with 99% of the plumbing so you can get real work done! I’m working on a sample issue tracking web application using this framework and was able to get a edit screen up and working within a couple of hours with just webforms it would be a lot, lot longer!!

The only thing lacking is documentation it’s one where your probably going to want to crack open the code to see what’s going on, but one great thing is the detailed exception messages you get which usually give you enough to get it sorted straight away, if only the BCL exceptions were this easry to understand :-)

Where can I find out more

June 27, 2008

New Staff Intranet Release

I have found enough spare time to put up a new release of the staff intranet project, for those who are not aware of this project it is a demonstration of using best practices, principles & patterns in a real world web application so if your looking for pointers or some code to use for your own applications go give it a look on codeplex.

In this newest version I have added AOP support to cut down on cross cutting code and also the ability to delete staff members from the GridView, most of the time spent was fighting against the asp.net controls (suprise, surprise) such as the GridView and the ObjectDataSource, I’m not sure what the guy(s) who created the ObjectDataSource object was smoking at the time but it must have been stronger than just tobacco :-)

My next release I want to demonstrate adding some service support showing how we can re-use existing code so they become little more than a remote facade (in theory!).

May 13, 2008

Writing your own Provider

Filed under: .net, advice, asp.net, c#, code example, tips, vb.net — Tags: , , , — Michael Cromwell @ 11:51 am

Writing the Provider base class

Providers need to have a base class they can inherit from to provide the necessary functionality for example:

public abstract class MenuProviderBase : ProviderBase
{
    public abstract IEnumerable<MenuItem> RetrieveMenuItems();
}

This base class should inherit from the ProviderBase class in the System.Configuration assembly, by convention it should be marked as abstract.

Custom provider collection class

You also need to create a provider collection class this will hold a collection of your custom providers:

public class MenuProviderCollection : ProviderCollection
{
    public new MenuProviderBase this[string name]
    {
        get {return base[name] as MenuProviderBase;}
        set {base[name] = value;}
    }

    public override Add(ProviderBase provider)
    {
        if (provider == null)
            throw new ArgumentNullException("provider");

        if (provider as MenuProviderBase)
             throw new ProviderException("Invalid provider type");

             base.Add(provider);
    }
}

Writing the configuration section class

 You need to have a way to translate the settings from the web.config file into an object that knows how to handle them, this is acheived by inheriting from the ConfigurationSection class:

public class MenuProviderConfigurationSection : ConfigurationSection
{
    [ConfigurationProperty("defaultProvider")]
    public string DefaultProvider
    {
        get {return base["defaultProvider"] as string;}
        set {base["defaultProvider"] = value;}
    }

    [ConfigurationProperty("providers")]
    public ProviderSettingsCollection Providers
    {
        get {return base["providers"] as ProviderSettingsCollection;}
    }
}

Using the ProviderConfigurationCollection allows us to rely on the built-in provider model to handle passing configuration values to our providers as you will see later on.

Writing a provider implementation

With the provider base class in place we can create our own custom provider implementation:

public class XmlMenuProvider : MenuProviderBase
{
    private string xmlFile = string.Empty;
    private string name = "XmlMenuProvider";
    public override Initialize(string name, NameValueCollection config)
    {
        if (!string.IsNullOrEmpty(name))
            this.name = name;

        this.xmlFile = config["xmlFile"];

        if (string.IsNullOrEmpty(xmlFile))
            throw new ProviderException("xmlFile attribute must be supplied");
    }

    public override IEnumerable<MenuItem> RetrieveMenuItems()
    {
        //... read xml file populate, perform some yield returns on matched nodes
    }
}

As I mentioned before by using the ProviderConfigurationCollection we get any attributes declared for the provider pushed into the Initialize method via the config NameValueCollection parameter pretty neat, you still need to make sure that the necessary settings have been placed in the config file like I’m doing for the xmlFile setting above.

Creating a provider factory

in order to get hold of a provider implementation we need somewhere where we can look at the config, grab the appropiate configuration section we declared above, instantiate the providers and pull out the one to use, this is something that we don’t want to perform everytime we ask for a provider so instead we use a factory that should only do this operation once and for subsequent calls it will give us a provider already instantiated, here’s the code:

public static class MenuProviderFactory
{
    private static MenuProviderBase activeProvider = null;
    private static MenuProviderCollection providers = null;
    private static readonly object locker = new object();

    public static MenuProviderBase RetrieveMenuProvider()
    {
        if (activeProvider == null)
        {
            lock (locker)
            {
                if (activeProvider == null)
                {
                    MenuProviderConfigurationSection config =
                                                                                 WebConfigurationManager.GetSection( "system.web/menuProviders" ) as MenuProviderConfigurationSection;

                    if (config == null)
                        throw new ConfigurationErrorsException("menuProviders section is not a MenuProviderConfigurationSection" );

                    providers = new MenuProviderCollection();
                    ProvidersHelper.InstantiateProviders(config.Providers, providers, typeof(MenuProviderBase));
                    activeProvider = providers[config.DefaultProvider);
                    if (activeProvider == null)
                        throw new ProviderException("unable to load default provider");
                }
            }
        }

        return activeProvider;
    }
}

We can utilize some of the classes found in the System.Web.Configuration namepsace, namely the WebConfigurationManager which can provider us our particular section by supplying it with the path location. Also we can use the ProvidersHelper class to instantiate the providers by passing in the provider settings from our configuration section.

Setting up web.config

After we have all the classes in place we then need to configure the web.config, firstly we need to add a section to the system.web sectionGroup, so inside the configuration element add the following:

<sectionGroup name="system.web">
    <section name="menuProviders" type="MyAssembly.MenuProviderConfigurationSection,MyAssembly"/>
</sectionGroup>

After adding that we then need to add the actual provider section, so inside the system.web element add the following:

<menuProviders defaultProvider="XmlMenuProvider">
    <providers>
        <add name="XmlMenuProvider"
                   type="MyAssembly.XmlMenuProvider,MyAssembly"
                   xmlFile="d:\inetpub\wwwroot\site\menu.xml" />
    </providers>
</menuProviders>

Usage

For this example we will assume we have our own menu control, the usage inside the Render method becomes:

public void Render(HtmlTextWriter writer)
{
    MenuProviderBase provider = MenuProviderFactory.RetrieveMenuProvider();
    foreach (MenuItem menuItem in provider.RetrieveMenuItems())
    {
        //... create html elements for screen
    }
}

Blog at WordPress.com.