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
}
|
You must log in to post a comment.