NBusiness 3 Updates

I’ve been working on NBusiness a little bit over the weekend. I’ve decided to create a Curried API using extension methods for the CodeDom to speed along template creation. Here is an example of what I have so far.

CodeMethodReferenceExpression onPropertyChanged =
 new CodeMethodReferenceExpression(null, “OnPropertyChanged”);
 
CodeMemberProperty memberProperty = new CodeMemberProperty();
memberProperty.Name = field.Name.ToPascalCase();
memberProperty.Type = new CodeTypeReference(field.Type);
 
memberProperty.Get()
.Return(memberField.Reference());
memberProperty.Set()
.If(             
    memberField.Reference().NotEqualTo(memberProperty.SetValue()))
.Then(
   memberField.Reference().Assign(
      memberProperty.SetValue()),
      onPropertyChanged.Invoke(memberProperty.Name));
Trust me, as ugly as the above seems it’s still a million times better than doing it all the way it was originally written. Hopefully this will mature and get better over time as well. Here is an example of the code it produces.
private int Aid {
 get {
   return _aid;
}
 set {
   if ((_aid != value)) {
      _aid = value;
      OnPropertyChanged(“Aid”);
    }
}
}
Secondly I have been polishing and simplifying the model framework that comes with NBusiness. I have been working to create an abstract DataAccess API that can easily produce any type of query. Here is an example of how you might insert a new model with the next version of NBusiness.
MockModel model = new MockModel();
model.Name = “testinsert”;
model.Save();
This is as normal and will end up calling into MockModel’s “InsertModel” method which may be implemented like so
protected override void InsertModel(IQuery query)
{
query.Insert().Into(
    MockModel.Database.Table,
    MockModel.Database.Name).Values(“@Name”);
query.Go();
query.Parameter(“@Id”).Direction = ParameterValueDirection.Output;
query.Parameter(“@Name”).Value = Name;
query.Load += loader =>
{
   Id = (int)query.Parameter(“@Id”).Value;
};
}
The DataBase.Table and DataBase.Name members are code generated, static ITable and IColumn fields based on your E# model definition. The query object will be passed up to parent objects and down to child objects and will be passed into an abstract provider which will use it to generate SQL and call your database. The IQuery object actually comes from your IDatabaseProvider and may abstract it to work with different databases. My theory at this point is that you could actually parse the query object anyway you like in the IDatabaseProvider and with a little manual work you could even get it working across a webservice.
Here is my MockDatabaseProvider for my unit tests. The provider interface is much simpler with this new technique.
class MockDatabaseProvider : IDatabaseProvider
{
#region IDatabaseProvider Members
 
 public IQuery Query()
{
    return new SqlQuery();
}
 
 public ITable Table(string name)
{
   return new SqlTable(name);
}
 
 public void Execute(IQuery query)
{
   MethodCall.Calls.Add(new MethodCall(
      “Execute”,
      new { Name = “query”, Value = query }));
 
   SqlQuery sqlQuery = query as SqlQuery;
           
    // Simulate setting the identity parameter after an insert
    IParameterValue id = sqlQuery.Parameters.FirstOrDefault(
      v => v.Name == “@Id”);
   
    if (id!=null && id.Direction == ParameterValueDirection.Output)
    {
      id.Value = 100;
    }
 
    sqlQuery.OnLoad(new MockLoader());
}
 
#endregion
}

Error Invoking AppDomain Proxy

I’m having one heck of an AppDomain bug. I have a situation where I am creating an AppDomain and then creating an instance and unwrapping it and invoking a method on that proxy instance. The first time I invoke this instance I get successful results and if I have a breakpoint inside of the proxy it will break on it, however the second time I invoke the method it will fail by yielding an incorrect return value.

Also, strangely enough, if I ever try to step INTO the method call with the debugger visual studio will suddenly shutdown. Examining the error code in the debugger doesn’t really reveal anything valuable either. Here is a link to the code in question:

ESharpCompiler.cs

Upgrading to NBusiness 2.1

I finally spent some time last night updating this blog site. I still have a few things that I want to do but I got some of the big things out of the way. The first big one was upgrading to NBusiness v2.1, actually it was pretty easy to do but I wasn’t sure how it would work out.

For anyone out there running 2.0.1 and thinking about upgrading to 2.1 I’ll try to list some issues you are bound to encounter. The first one is the change from using the static CreateNew() method to using constructors. so if you have code like this:

Blog blog = Blog.CreateNew();

You will need to change it so that it looks like this:

Blog blog = new Blog();

Much better if you ask me! Also the old create new methods will still be generated but it will give you an obsolete error message so you can find and change them easily. You may also have to change references to NBusiness in your website, i had to alter a web.config file that had version information in it. Other than that I had to run the sql stored procedures it created on my new site to get it to work which is fine.

Also there is one big problem I encountered and that is that the scripts will generate sibling relationship tables and scripts and keys at the bottom of “complete.sql” not at the top with the rest of the tables! Which means if you try to run just the scripts be sure to search for ALL of the table drop/create scripts because I accidentally dropped my BlogsTopics tables when upgrading. Which turned out to be ok because I wanted to redo them anyway (I had too many useless topics) but it could have been really bad in a bigger site.

I’ll probably make NBusiness v2.1 available as the primary download on codeplex later today (you can get it right now from the planned release section).

The biggest new feature of NBusiness 2.1 is the ability to use some generated objects to create dynamic sql. So when you go to create custom fetch methods its much faster than the current system. The other features are listed on the download page.

Dynamic SQL for NBusiness

I have been working on adding the ability to do dynamic SQL for NBusiness business objects. The point of this basically to allow a developer to quickly add new Fetch factories. Currently if you want to add a new fetch factory you need to do a few steps.

·         Create the factory method

·         Create the Criteria class

·         Add a handler to the Fetching event

·         Add a case to the fetching handler for your criteria object

·         Then call the Database Provider

·         Create the necessary stored procedure

Since needing to create new Fetch factories is a pretty common task I wanted to add a way to make it easier. NBusiness will generate all of the most common Factories and stored procedures for you (such as factories for fetching all entities or fetching by id’s or relationships) but if you want to be able to fetch by some other column type you’re stuck with creating your custom factories. For example if you wanted to search for all Customers with the first name of “justin” you’d need to create a FetchByFirstName(string name) factory.

So now rather than going through all of the steps above you can simple create your Fetch factory using dynamic SQL and pass that into the Database Provider instead. There is an object model for creating this dynamic SQL and NBusiness default templates will generate for you all of the Table and Column objects corresponding to your entities.

So for example if you have a Customer entity and you want to fetch by first name you might create a factory method that looks like this:

public static TopicCollection FetchByFirstName(string name)

{

    IQuery query = Topic.Queryable.Table.Where(

        Topic.Queryable.Name == “@name”);

       

    return new TopicCollection(

        query,

        new Parameter(“@name”, name));

}

NOTE: exact syntax may change; this is just an example of how I have it now.

Also, when we upgrade to Visual Studio 2008 these objects will be LINQ queryable. Meaning if you query your entities within a LINQ statement it will generate dynamic SQL for you to fetch the data for your entities (yes, like DLINQ).

Different Database providers will be able to implement their own Query classes so that SQL can be generated for different types of databases. For now I will just implement it for SqlServer 2005, in fact I’m probably going to push back the release of the MySql provider stuff just because as far as I know there isn’t really a demand for it at this point and it’s more work than it’s worth given that fact.

NBusiness integration with Visual Studio 2008

The Visual Studio Extensibility (VSX) team has recently written a blog post announcing the Visual Studio 2008 SDK 1.0. I am pretty excited for this I will be probably wrapping up the last touches on NBusiness v2.1 soon and release it so I can get on to working with Visual Studio 2008. I’m pretty excited about it actually. Once I release it I will write a blog post outlining some of the changes and new features.
The one question I have at this point is when hosting providers (such as Go Daddy) will be providing the .net Framework v3.5 on their servers. I believe that they don’t even have v3.0 right now so I’m a little skeptical that they’ll be providing support for 3.5 anytime soon. However it really seems like that, even though 3.0 have been out for a while, a lack of official tooling has caused a lot of people to stick with 2.0 and VS2005 for the time being. There are lots of exciting things about VS2008 and .NET 3.5 and now that it’s all officially released I bet we’ll see a surge in applications using this technology and probably prompting Go Daddy (and others) to support it.
Along these lines I have been playing around with the new MVC framework some and I have to say… it’s pretty damn nice. I am all for dropping the overly complex ASP.NET page life cycle we currently have to deal with. Other than some issue I was having with rendering a custom view (could be my fault but it’s basically an Alpha preview so I expected a few issues, I’m not really worried) I definitely prefer this model. Without a doubt NBusiness will fit in nicely as the “model” portion of the framework.
I also went ahead and used the LINQ to SQL datasets that come with the v3.5 framework to see how that works to… wow it’s great. In fact I’m sort of going through a bit of an identity crisis with NBusiness as I try to decide if it’s even worth bothering to try to compete with it. I’m trying to come up with enough benefits in NBusiness to outweigh the benefits of LINQ to SQL before I decide to really go for it.
So here are a few of the reasons that I have come up with so far, they’re mostly just cerebral arguments at this point I can’t say that they’re correct because when it comes down to it I think that it’s practicality that really decides what is better.

In favor of NBusiness

NBusiness supports business objects

Data validation, access and authorization rules are all very easy to setup in NBusiness. You could still probably do this with the objects generated by the linq to sql datasets but it doesn’t appear to be built right into the base class objects nor is there a way to specify these things in the designers.

NBusiness is not dependent on a database for metadata

The datasets are dependent on having an active server connection, I’m not sure how it works exactly but I’m guessing it is pulling in the schema each time you build. I’m not sure how well I like this, there are definitely lots of problems with this such as the situation where the database has yet to even be designed or you have a large database with lots of columns and tables. There are ways to deal with these situations but I’m not sure as a matter of principle that I really like having my build process dependent on pulling meta-data out of another process at build time. It would be really nice if you could just have SQL scripts lying around and it was able to infer the schema out of that but as far as I know that isn’t how it works. Also, of course mapping your objects to your database 1:1 is undesirable and it is yet to be seen how editing a data set in design mode will be when working with a large database full of ugly naming conventions and missing key constraints and all of the other various problems legacy databases tend to have.
In the case of NBusiness, your entity definitions are the metadata for your build process. It can generate for you a simple database based on those definitions but in the case of an existing database or legacy database will do the mapping in stored procedures yourself but you end up with business objects rather than a data access layer.

NBusiness code is template driven

You have full control over the code that is generated. Maybe I’m wrong about this but I didn’t see any obvious way to change what is output by the designer when you build your project. The objects that the designer creates are partial classes, so that’s nice that they can be extended but what if you want to control everything about their output? It seems (at first glance) that they are breaking one of the 5 laws of code generation.

NBusiness prefers stored procedures

I’m a little skeptical about the dynamic SQL approach used by LINQ. I mean it’s nice to be able to do dynamic sql but it seems wise to use stored procedures as much as possible and probably exclusively. For small applications where you’re trying to rapidly produce results and performance isn’t really that big of a deal for certain uncommon calls, sure do dynamic SQL. But the backbone of your application should really be with stored procedures. I believe it is possible to call stored procedures still with these datasets but I really seems like there is a heavy focus on LINQ and dynamic SQL which will no doubt result in entire applications using dynamic SQL everywhere, which I’m skeptical of.
I have recently added support for dynamic sql in NBusiness (v2.1). It’s obviously not as well tested and robust as LINQ to SQL at this point but it’s pretty good I think. In the 3.0 version there will probably be a way to use LINQ directly on NBusiness objects just like with these datasets too (I’ll probably write another post about this). But I would like to keep the preference of NBusiness strongly on stored procedures as much as possible.

In favor of LINQ to SQL Datasets

Awesome tooling

Of course the VS integration blows NBusiness out of the water. It’s fast and pretty and everything works like it should. This alone is a good reason to use it over NBusiness. I believe I can get NBusiness to this point eventually but it is definitely going to be hard. Also there is nothing extra to download or install to get this working; it’s just built into VS 2008, very hassle free.

Very lightweight, simple, flexible

It’s so easy once you have your database created and the objects it makes are so lightweight and simple there is virtually no learning curve. It’s so light weight it’s almost worth just saying ‘screw it’ to the robust business object in favor sweet simplicity. I’m actually struggling with this one the most at this point. I suspect that a larger application may push this theory over the edge however.

Promotes database to be designed separately

I have this theory that having a single source of meta-data (or the source of truth) rather than being dependent on a database’s schema for meta-data is superior. However I’m having some doubts right now. Shouldn’t it be true that separating the concerns of the database and the objects by handling them in separate tools be the most correct theory? What is the best strategy for bridging these two together? The implementation of DLINQ is so good it’s causing me to doubt myself here.
I’m still leaning towards continuing on with NBusiness and with some of the new 3.0 features I have been kicking around in my head it will be even better than it is now but I just want to make sure I’m not wasting my time here. I want to really think about it and make sure I continue on, not as a victim of my own ego but because it is genuinely a worthwhile endeavor.