Gratuitous Use of Linq

by Jacob 7. March 2009 06:10

PowerShovel Every now and then I get to doing something just because... well, because I can. These projects usually atrophy before becoming anything usable and serve more as a way to explore and practice than anything else. Usually. My latest tangent actually got to a state where I can let it loose in the wild and it'll probably actual do what it is supposed to do.

BlogEngine.Net

Let me be perfectly clear up front: I don't actually use BlogEngine.Net at all. Anywhere. I'm still a Subtext guy when it comes to blogging software. BlogEngine.Net still lacks critical features and that prevents me from using it as yet (primarily running multiple blogs from a single installation/database).

That said, BlogEngine.Net is a lovely little product with a lot to like about it. The extensibility model is extremely easy to use and flexible. The theming doesn't suck. And its architecture is easy to navigate/understand even while it makes investments in areas I consider likely to payoff.

Data Access

While I like the product, the data access bugs me more than a little. It uses a provider model and includes built-in XML and database providers. These are good things. For flexibility, the database provider uses System.Data.Common and the DbProviderFactory with string-built commands. This structure allows BlogEngine.Net to be able to use any database that has a .Net data provider (including things like MySQL, SQLite, or VistaDB). Incidentally, they downplay (unintentionally?) this feature on their website saying in their FAQ that they support XML and “the SQL Server provider”.

At any rate, here's their SelectPage implementation as an example

public override Page SelectPage(Guid id)
        {
            Page page = new Page();
 
            string connString = ConfigurationManager.ConnectionStrings[connStringName].ConnectionString;
            string providerName = ConfigurationManager.ConnectionStrings[connStringName].ProviderName;
            DbProviderFactory provider = DbProviderFactories.GetFactory(providerName);
 
            using (DbConnection conn = provider.CreateConnection())
            {
                conn.ConnectionString = connString;
 
                using (DbCommand cmd = conn.CreateCommand())
                {
                    string sqlQuery = "SELECT PageID, Title, Description, PageContent, DateCreated, " +
                                        "   DateModified, Keywords, IsPublished, IsFrontPage, Parent, ShowInList " +
                                        "FROM " + tablePrefix + "Pages " +
                                        "WHERE PageID = " + parmPrefix + "id";
 
                    cmd.CommandText = sqlQuery;
                    cmd.CommandType = CommandType.Text;
 
                    DbParameter dpID = provider.CreateParameter();
                    dpID.ParameterName = parmPrefix + "id";
                    dpID.Value = id.ToString();
                    cmd.Parameters.Add(dpID);
 
                    conn.Open();
                    using (DbDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            rdr.Read();
 
                            page.Id = rdr.GetGuid(0);
                            page.Title = rdr.GetString(1);
                            page.Content = rdr.GetString(3);
                            if (!rdr.IsDBNull(2))
                                page.Description = rdr.GetString(2);
                            if (!rdr.IsDBNull(4))
                                page.DateCreated = rdr.GetDateTime(4);
                            if (!rdr.IsDBNull(5))
                                page.DateModified = rdr.GetDateTime(5);
                            if (!rdr.IsDBNull(6))
                                page.Keywords = rdr.GetString(6);
                            if (!rdr.IsDBNull(7))
                                page.IsPublished = rdr.GetBoolean(7);
                            if (!rdr.IsDBNull(8))
                                page.IsFrontPage = rdr.GetBoolean(8);
                            if (!rdr.IsDBNull(9))
                                page.Parent = rdr.GetGuid(9);
                            if (!rdr.IsDBNull(10))
                                page.ShowInList = rdr.GetBoolean(10);
                        }
                    }
                }
            }
 
            return page;
        }

I want to reiterate that I'm not ripping on their choice to use this data access methodology. If you want the flexibility to use any .Net supported data provider without a third-party dependency, this how you get it. You could optimize some of the stringiness, but with trade-offs.

Linq, Linq, Baby

That said, I don't mind being tied to SQL Server and if I'm going to muck with the data layer (like, say, if I'm going to attempt multiple blogs from a single application instance) I want something simple that I can use without all that extra goo. I looked for any hint that this might have been done already, but I couldn't find anything. It looks like I'm the only one with this particular manifestation of brain damage, however.

Since configurable table prefixes are a desirable feature and since that's easier to do in Linq to SQL I figured it'd be best to go that route. It was good to get the table prefix stuff into a working project and have it work about as I expected it to.

Implementing the BlogEngine.Net blog provider turns out to be pretty easy in Linq. Ditto the Role and Membership providers. I tried to stay as close as possible to the DbBlogProvider. Even so, I found that some of the admin components are picky enough that even little things could bite me (the category editing page blows up if you leave category descriptions null, for example).

For compare and contrast, here's my SelectPage method using Linq to SQL

public override Page SelectPage(Guid id)
{
    Page page = null;
    using (Data.BlogDataContext context = getNewContext())
    {
        Data.Page pageData = (from p in context.Pages
                              where p.PageID == id
                              select p).FirstOrDefault();
        if (pageData != null)
        {
            page = new Page()
            {
                Id = pageData.PageID,
                Title = pageData.Title,
                Description = pageData.Description,
                Content = pageData.PageContent,
                Keywords = pageData.Keywords,
                DateCreated = pageData.DateCreated.HasValue ? pageData.DateCreated.Value : DateTime.MinValue,
                DateModified = pageData.DateModified.HasValue ? pageData.DateModified.Value : DateTime.MinValue,
                IsPublished = pageData.IsPublished.HasValue ? pageData.IsPublished.Value : false,
                IsFrontPage = pageData.IsFrontPage.HasValue ? pageData.IsFrontPage.Value : false,
                Parent = pageData.Parent.HasValue ? pageData.Parent.Value : Guid.Empty,
                ShowInList = pageData.ShowInList.HasValue ? pageData.ShowInList.Value : false
            };
        }
    }
    return page;
}

BlogEngine.Net for SQL Server

So I got the thing working and thought I'd open it for “the community”. Since BlogEngine.Net is on CodePlex, that was a natural choice. Anyone sharing my peculiar proclivity is invited to head on over, take a poke and let me know what can change for the better. Or better yet, submit a patch. Or better, better yet, join the project. (also: CodePlex's recent transparent svn compatibility is awesome! When did that happen?)

If you do poke at the project, some forewarning. First, I don't have unit tests for this and don't plan on any (I'm not against using them, I just don't want the headache of creating them myself). Data access is more in the realm of “integration testing”, so I'm not sure there's much you can really do that's actually useful. It might be different if BlogEngine.Net had a suite of tests I could use to validate my providers against, but...

Second, I haven't gone out of my way to do a lot of commenting. This is deliberate. These methods are short, should be self-explanatory, and since they should be hidden behind a provider I didn't even bother with the typical XDoc stuff. Anything directly accessing them such that intellisense comes to bear is doing something wrong...

Room to Improve

In the end, this is the ground-work to remove an (admittedly trivial) barrier in working with BlogEngine.Net. I hope to help move as much as possible into the database in order to support things like multi-blog configurations. BlogEngine.Net hasn't been very disciplined in its storage layer and XML really is the default medium. Things like referrer tracking don't use a provider at all so you really can't (yet) get away from XML files in your App_Data directory (and hence, read/write permission configuration). Since I want that to change, I'm going to see if I can't get that going a bit.

Things to do
  • Decide on a database update methodology (so far, I'm using the already-existing tables and hence piggy-backing on the BlogEngine.Net scripts)
  • Replace the built-in ReferrerModule (use/create provider model access for referrers?)
  • Comb the project for any other errant XML dependencies
  • Work on multi-blogging configuration

Tags: , , , , , ,

Programming

Putting Dependency Injection in its Place

by Jacob 13. June 2008 05:27

Careful Placement You might say that I’ve had issues with Dependency Injection in the past. Well, with all the things I’ve learned not to do, I thought I’d go into a case where I’m considering dependency injection because it looks like it might be a good fit.

Project Background

Like many (most?) developers, I’ve been involved for many years in a particular vertical market. Like most, my involvement in that vertical market includes acquiring a substantial amount of very specific domain knowledge. I’m sometimes reluctant to admit it, but I spent a good decade and more of my career writing software designed for Multi-level Marketing companies. Specifically, I wrote programs that calculate the commission payments to their distributors. If you are familiar with that domain, my condolences. If you are considering entering that domain, talk to me (it’s not all bad).

Now, many accounting software packages deal with paying commissions, but compared to even the simplest MLM, their capabilities are pretty primitive. I won’t go into the full complexity of walking a tree with money on the line, but here’s what’s important for this post:

  • The data you have to process is well contained, finite, and known in advance.
  • Data concurrency tends not to be an issue (you read distributor information at the beginning and you write payout and promotion information as you go or at the end).
  • Every company has their own, unique twist for qualifications, promotions, and payouts—indeed, commission plan differentiation is a key business differentiation.
  • The only thing absolutely common to every commission plan is that you walk a tree of distributor nodes, processing orders at those nodes, and calculating payouts and/or promotions on them.

Most programmers working in that domain spend time designing their dream "bonus engine". One that can encapsulate the common elements so that their programming only has to deal with the payout and promotion logic. This turns out to be harder than you’d think to do right (if only due to the temptation to put more in the engine than really belongs there).

My Bonus Engine

Since I’m still getting occasional contract work programming commission payouts (and because I’ve seen a bonus engine or two and know what works and what doesn’t), I went and created an OSS bonus engine. Those of you dying to critique my code-fu to bring me up for well-deserved mockery, here’s your chance. So far I’m the only dev on the project, but that’s only because I don’t know anybody else masochistic enough to join me (hey, if you’re that nuts, let me know).

Right now, this engine is still pretty raw, but it works. Mostly. There are INode and IVolume interfaces for distributors and orders respectively. There’s a NodeBase object that implements INode with nifty events already implemented for easy inheritance and feedback and there’s a BonusManager object used to kick off a bonus run.

The tricky bit for this post is the data access. You see, when programming commission payouts, I seriously don’t care where the data comes from or where it is going. My clients all have their own tricky little data schemas and I’d just as soon not deal with the ins and outs of their systems. Abstracting that part out is beneficial all round.

In my initial design, I figured that something like that is a classic call for an Asp.Net-like provider model. This works well because the client can implement a provider (or have me create one for him) that we can drop in and we’re golden. That means that my eventual Distributor objects can be ignorant of all data implementation details and make a call to MLMBonus.DataProvider.BonusData.Promote() to notify of a promotion (for example).

Making the method references static seems like a good call because the distributor object has no other contextual information available. The engine is walking a tree and calling interface methods so the distributor and volume objects don’t really know much more about the outside world than their relationships to each other.

Because this is my first ever implementation of a "Provider Framework", I went digging for some sense of what kinds of things to look out for. While I initially went with an interface structure, I eventually decided to use Joel Ross' well written guideline for creating your own .Net providers.

There’s Always One

Unfortunately, I got some push-back when talking with my favorite client. You see, he’s chafing at the static nature of my provider model. He wants to make a grab for the holy grail of bonus commissions—executing mini-commission runs on-demand (most likely for partial distributor trees)—and the static provider just isn’t cutting it for him. mini-commission runs allow you to provide some interesting features to your distributors and that’s never a bad thing.

To support his functionality, he would need to be able to alter the data provider "on the fly" and/or be able to initiate multiple runs in the same application space without allowing them to step on each other. There’s just no way that static providers are going to work for that functionality. Naturally, I’ve been thinking about how best to work out meeting his need (mainly because I can see this feature will be something others will like but also because he’s my favorite client). Fortunately, my engine isn’t widely disseminated so it’s a good time for wholesale architectural alterations if we want to make them.

I’ve considered a number of ways to tackle the problem, playing with things like anonymous methods and context managers. They all turned ugly fast so it’s time that I face the fact that this functionality is pretty much tailor made for Dependency Injection.

Where To Inject

So where’s the best place to inject this little dependency? There are four options as far as I can tell.

  • constructor injection
  • property (or setter method) injection
  • method parameter injection (since the number of methods affected will be very small).
  • framework injection (Spring.Net or Castle Windsor for example)

Constructor and property injection are both object level references carried by the dependant object and have little to distinguish them in effect. Conceptually, I’ve heard that constructor injection is best for dependencies that are crucial to an object—something the object simply cannot do without. I think I agree with that guideline but I also like the convenience of being able to do grunt-work things in constructors, so if I were in charge of the objects, I’d include both a base constructor and one that includes the dependency as well as a setter method of some kind.

Method parameter injection is tempting, though. With method parameter injection, a client can set the dependency on BonusManager and rely on BonusManager to send the dependency to the Pay and Promote methods on INode. That way the reference to the data provider is short lived inside INode and IVolume objects. Thinking it over, though, I’m not sure why I’m so worried about carrying a bunch of references when garbage collection isn’t going to happen mid-run anyway. Yeah, there’s some overhead involved in tracking the reference on each INode object, but it’s negligible (are pointers in a 64 bit environment 64 bits long? They’d pretty much have to be right? I’ve never bothered to find that out—it’s never been significant before).

Framework injection simply isn’t going to be helpful in this case, I don’t think. For one, I’m not familiar enough with any DI Frameworks to make it worthwhile. For another, I don’t want to introduce a framework dependency on the project. And finally, I don’t want to commit future clients to a DI Framework that may be an issue in their environment.

Injecting

So my next task for the engine will be to muck around with the EngineInterfaces library. I’m thinking I’ll leave the provider object as-is (the BonusDataProvider abstract class) and simply add a property to INode to inject that sucker. In addition, I’ll update NodeBase to have an appropriate property and a new constructor that allows you to set the provider property on object creation.

Since I have the provider stuff already in place and no changes are needed to make this work, I’ll likely leave it alone. That way I won’t break anything currently working.

The only thing left is to decide if I want the IVolume dependency injected via a field or a method parameter on Pay. I’m pretty sure I don’t need the fine-grained control of allowing different orders for a single node to pay down a different path, but do I really want to commit to that? My arguments above against method parameter injection seem pretty solid for the IVolume object as well, but I haven’t completely convinced myself that they apply as strongly.

Tags: , , , , , ,

MLMBonus | Programming

Tilting at Windmills

by Jacob 16. August 2007 00:59

Windmill I’ve been giving poor Nate Kohari a hard time over at Discord & Rhyme. He has been very patient in Defending Dependency Injection. His attitude stands in sharp contrast to Ayende Rahien's post today about testing Linq for SQL. Ayende’s snide "(Best Practices, anyone?)" is exactly the attitude I lamented in my original post on Dependency Injection when I said

I do wish that people would admit that DI doesn’t have compelling applicability outside of Unit Testing, however. I’m reading articles and discussions lately that seem to take the superiority of DI for granted. And I’ve read mock object examples that seem a little bit condescending about dependency injection—as if your projects should already incorporate this technique.

I find myself reflecting more and more on how liberating TypeMock is and come back to wondering again if Dependency Injection would exist as a pattern at all if it weren’t for unit testing.

My hypothesis (entirely untestable, so technically a mere speculation) is that what happened is that in order to achieve 100% code coverage in their unit tests with methods that read databases or call web services or have other potentially nasty dependencies, someone came up with the neat idea to invert control of those dependencies so that unit tests could feed in an abstracted object that fakes those calls and the real logic of the methods could be tested without bothering the poor database (or whatever). That’s a noticeable, pervasive, broad architectural change, though, especially if it is only used for unit testing, so in order to defend their idea, developers began looking for additional justification for this pattern. Since nobody but Microsoft uses providers (and that really only in Asp.Net) and software factories are so last year, they cannibalized the strengths of both and pushed them down to the object level and called it done. I’m not saying they did so maliciously or dishonestly. I’m just saying that they needed further justification and that the justifications they chose are already served by applying other useful patterns.

Seriously, with providers that allow you to contextualize defined sub-systems and something that allowed you to Mock objects in testing without having to feed those objects to the tested class, can you think of a good reason to use Dependency Injection? Any dependency that needs to be altered more frequently than a contextual provider framework would allow needs to be exposed for access by calling objects anyway, I’m thinking.

This thinking was crystallized as I explored some of the DI frameworks referenced by Nate. As I watched Kevin Bourillion and Bob Lee explain their Guice for Java framework (a DI framework created by Google), I was struck by the number of references to testing. From that presentation alone, it looks like the main impetus for Guice was unit testing and the other benefits described would have been as easily satisfied with a provider framework.

Come to that, it could be that solid DI frameworks like Guice and Castle Windsor have a niche when it comes to making providers easy to create, control, and use.

Still and all, I wonder what would have happened if they had invented something like a Java version of TypeMock for their mock objects first.

Tags: , ,

Programming

scruffylookingcatherder.com

Information

    Recent Posts

    Calendar

    <<  September 2010  >>
    MoTuWeThFrSaSu
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    View posts in large calendar
    Disclaimer
    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010 Scruffy-looking Cat Herder