Query added to WilsonORWrapper

I just updated WilsonORWrapper to include a Query<T> class that simplifies using OPathQuery<T> objects. To illustrate, I’ll take the content from the newly-written Services page on the project wiki (which also gives an overview of the Data<T> service).


The Query service provides a simple interface to generating OPath queries. It helps simplify code by avoiding the need to explicitly use the Wilson.ORMapper namespace to generate OPathQuery objects.

Using the Query service is best illustrated by comparing how you would generate an OPathQuery using the Wilson.ORMapper namespace, and how you would generate a query using the Query object (which hides the underlying OPathQuery object from your code).

Querying using OPathQuery<T>

using Wilson.ORMapper; 
using WilsonORWrapper.Services; 
... 
OPathQuery&lt;User&gt; query = new OPathQuery&lt;User&gt;("Name = ?");  
User user = Data&lt;User&gt;.Retrieve(query, "Brian"); 

Querying using Query<T>

  
using WilsonORWrapper.Services;  
...  
Query&lt;User&gt; query = new Query&lt;User&gt;("Name = ?");  
User user = Data&lt;User&gt;.Retrieve(query, "Brian"); 

Note the similarities of the code. The usage of Query<T> is the same as OPathQuery<T>, but you are saved the hassle of dealing with a separate namespace.


I hope you find this helpful, and as always, please give me your feedback on the project.

Download the source code for this release (r41). (Compiled distributions are not currently available.)

WilsonORWrapper: better, stronger, (maybe) faster

About a month ago, I wrote about a major update coming to WilsonORWrapper, the code library/code generation templates I put together for Paul Wilson’s O/R Mapper. Finally, it’s available!

The source code, releases, API documentation, and some (but far from enough) how-to sections are available on the WilsonORWrapper project site.

For those who used the previous version of the wrapper, there are some major breaking changes in here, but it’s not incredibly time-consuming or difficult to make the transition. The namespace hierarchy is changed somewhat, the configuration settings are changed, and some core classes have different method names, but overall it shouldn’t take long to convert. (I converted a project with about 30 entity classes in about 60 minutes.)

Every few days, I’m going to add to the “how-to” documentation, focusing on a different part of the library each time. Until then, there’s still plenty of stuff to check out.

If you find an error, please create a ticket on the project site. If you have comments or suggestions, post them here or on the WilsonORWrapper project page on this blog.

Major revamp of WilsonORWrapper coming

A few weeks ago, I released WilsonORWrapper, a framework built around Paul Wilson’s O/R mapper. Since then, I’ve been busy rewriting it, improving existing features and adding new features to the mix.

There’s a lot of changes coming, and there are many breaking changes. Among the biggest changes include:

  • Single assembly distribution. The previous Entities and Services namespaces are now combined into a single DLL.
  • Integrated logging services. Logging services to log to the Windows Event Log or to text files using NLog or Log4Net is included. O/R mapper command interception is activated for all debug logging levels. Adding other logging services will be easy in the future, thanks to a pseudo-provider model.
  • Integrated cache services. A caching framework is available, and a cache interface to the ASP.Net cache is included. Caching to memcached will be added in the near future. Adding other caching services will be easy in the future, thanks to a pseudo-provider model.
  • Simplified configuration and initialization. Simple in that it’s not required unless you want to change default settings, and everything is done from your application’s config file. Further, all components are self-initializing — just write code, no need to call any initialization or construction methods.
  • Improved services interface. Want to retrieve an object? Use the Retrieve<T> static class. Persist an object? Use the Persist<T> static class. Access the logger? Use the Logger static class. (A static Cache class is yet to be written.)
  • Extensive unit tests on the framework to ensure things work.
  • Updated CodeSmith templates work just as they did before.

The current code release for this is available in the “combined” branch of the Subversion repository. There’s still more work to do before this release replaces the current trunk, but I wanted to give those few who pay attention to this project a heads-up on the forthcoming changes.

Feel free to check out the current code distribution and let me know what you think.

Choosing method names for a cache interface

As part of the overhaul of the WilsonORWrapper, I’m adding a cache service. To do this right, I need to implement an ICacheClient interface. This interface will define the methods and properties which any cache client will need to implement.

Sounds simple on the surface, but I quickly ran into a problem. What do you call your methods? Consider the following possibilities for naming four core methods.

  • Retrieving an item from the cache: Get, Retrieve, Load, Fetch, Read, Select.
  • Placing an item in the cache: Put, Set, Add, Insert, Save, Update.
  • Determining if an item exists in the cache: Contains, Exists, Has.
  • Remove an item from the cache: Remove, Delete, Clear.
  • Clear all items from the cache: Flush, Clear, ClearAll, DeleteAll, RemoveAll.

The worst part of determining a naming convention is that you are generally stuck with it once you choose it, unless you want to implement breaking changes into your application.

Most of the names above were found in some cache API currently in existence today. (I did a Google search to find as many as possible.) Some of them are not recommended because their usage is uncommon (such as Fetch, unless you have a DogCacheClient). I’d also stay away from the *All methods — they sound good on paper, but the difference between Remove and RemoveAll is quite big, and you can call the wrong one if not paying sufficient attention.

With those left over, you can organize them into groups based on similarity of use in well-known applications, languages, and APIs.

  • SQL Style: Select, Insert, Update, Exists, Delete, Clear.
    This style is good if you expect to have separate Insert and Update methods, where Insert can only add new items, and Update is used to change existing items.
  • Collection Style: Get, Add, Contains, Remove, Clear.
    The common naming used in Microsoft and Java collections.
  • Simple Style: Get, Put, Has, Remove, Clear.
    Short and sweet. You can arguably combine Remove and Clear if you’re brave.

Which one should I use for the WilsonORWrapper? One thought is to use the SQL style, since this is a wrapper for an O/R mapper, which is closely tied to SQL. However, I don’t want separate Insert and Update methods. Also, the point of the wrapper is to allow people to write in code, not in SQL, so the relationship to SQL should not dictate style.

That leaves us with the simple style and the collections style. NHibernate uses the simple style in their Cache API. Microsoft’s System.Collections namespace uses the collection style. I’ll go with a combined version: Get, Set, Contains, Remove, Clear, mostly for the reason that users of WilsonORWrapper are probably more familiar with Microsoft Collections than NHibernate, and because I prefer Set over Add.
Have you seen, or used, other naming conventions in your travels?

Introducing WilsonORWrapper: A wrapper for Paul Wilson’s O/R Mapper

Earlier this month, I wrote about a revamp to the O/R mapper templates I’ve been working on, and included a demo project that included a working sample. Since then I’ve continued some work on these, have cleaned up the project, and added it to a public Subversion repository. Rather than write a lengthy introduction, I’ll just cut-and-paste (and reformat) the text from the readme file in the repository.

Wilson O/R Wrapper

What is it?

WilsonORWrapper is a framework that wraps around Paul Wilson’s O/R Mapper (“WORM”) that creates entity objects and a service layer for your O/R mapper objects. It is implemented as a set of assemblies that provide base functionality and a set of CodeSmith templates that can autogenerate your entity and service layers.

Who wrote it?

The author of the WilsonORWrapper project is Brian DeMarzo. However, a large part of the code contained within it is derived from CodeSmith templates by Paul Welter. Other smaller code blocks are derived from general tips pulled from various web sources; credits to the authors where relevant are given within the source code.

How to use it

To use the wrapper, you first need to do three things: create your database, create your mappings file, and create your projects.

CodeSmith templates are provided to build your mappings file, which you should always review and edit manually after creation.

CodeSmith templates are provided to build your entity and service classes. These templates will also create or update a Visual Studio project for both your entity and service layers, and will optionally create a test project (NUnit required).

Further information can be found at the WilsonORWrapper web site. Source code (which includes an example project) can be downloaded from the Subverson repository or from the project web site.

Revamping the O/R Mapper CodeSmith templates

I took some time over the weekend to make big changes to my CodeSmith templates for Paul Wilson’s O/R Mapper. The changes are significant, so read on if you use them or plan on using them or are curious about them.

The biggest change is that I am removing the static service classes from the templates and distributing them as stand-alone libraries. Of course, source code will be provided along with DLLs. Considering these classes were rarely changed by users, it makes sense. It also makes the library much more accessible to folks who don’t own CodeSmith — now, CodeSmith is used to generate your project’s entity and service classes, not the framework library. This opens the door for more users of Wilson’s O/R Mapper to use this framework.

As a result, in a clean distribution, you would have the following:

  • ORMapper.Services.dll
  • ORMapper.Services.Log4NetIntegration.dll
  • ORMapper.Services.NLogIntegration.dll
  • ORMapper.Entities.dll
  • CodeSmith templates to generate your project’s entity classes, service classes, and unit tests

The first four are the stand-alone libraries (assemblies) previously created as part of the CodeSmith templates (things like DataManager and TransactionManager, both of which are now called DataService and TransactionService). Only the first two are needed (Services and Entities). The Log4NetIntegration and NLogIntegration assemblies are used only if you want to integrate such logging into your service layer (more on that soon).

ORMapper.Entities

The ORMapper.Entities library provides the interfaces and base classes for all your entity objects. Not much has changed in here. All user entity objects derive from EntityBase<T> (read-only entities) or PersistableEntityBase<T> (updateable entities). The IIdentity interface is implemented by your project’s identity classes.

ORMapper.Services

The ORMapper.Services library provides the service classes to do the actual data retrieval and manipulation. It includes the singleton classes DataService (the service that exposes the underlying Wilson O/R mapper engine), TransactionService (simple transaction management), RetrieveService<T> (a generic class for retrieving entity objects), and PersistService<T> (a generic class for persisting entity objects).

A new ServiceLayerConfiguration class allows configuration settings to be provided in your application’s config file. This is a standard configuration handler that you register in your configuration file as follows:

<configuration>
    <configsections>
        <section name="serviceLayer" type="ORMapper.Services.ServiceLayerSettings,ORMapper.Services" />
    </configsections>
    <servicelayer mappingsFile="Mappings.config"
           connectionString="ORMapper"
           logger="" />
</configuration>

The values shown above are default values. Unlike in the past, your Mappings.config file must be copied to your output directory on compilation (in the past it was an embedded resource).

By specifying nlog or log4net as your logger, and by referencing the appropriate integration library assembly with your project, logging will be added automatically using the appropriate logger. This method allows easy switching between libraries and opens the door for adding other logging mechanisms in the future.

NLog integration will use NLog’s standard methods for finding a configuration file (application config, nlog.config, etc.). Log4Net integration will by default look in the application configuration file for settings unless you specify the name of your configuration file in an application settings key named log4net-config-file, as shown below.

<appsettings>
    <add key="log4net-config-file" value="log4net.config" />
</appsettings>

The above would tell log4net to get its configuration from a file named log4net.config (by default in your application’s startup directory).

CodeSmith Templates

There are two CodeSmith templates provided. The first, MappingsFile.cst, will generate the Mappings.config file based on a given database. (Unlike in previous distributions, this one works.) The second, ClassGenerator.cst, will generate your project’s entity and service classes based on a Mappings.config file.

The entity classes are much as they were in the past. Partial classes separate auto-generated code so you can safely add functionality without overwriting it by re-running the templates, and an IIdentity class is created for each entity. Note that the templates will generate uncompilable code if you do not have a primary key specified, so be sure to specify a primary key for each table. (Why you wouldn’t do this anyway, I have no idea.) Entity classes are now generated in a separate project uncluttered by the library code that now exists in the ORMapper.Entities assembly.

The service classes are new, and provide a simpler mechanism to expanding your service layer. Each of your entity classes will be given a (singleton) service class, which will be little more than a strongly-typed wrapper around the RetrieveService<T> or PersistService<T> class. Partial classes are used to separate auto-generated code so you can safely add functionality, much like with entity classes.

How does this change things? In the past, you would retrieve and update a User entity by writing the following code.

User user = Retrieve<user>.RetrieveFirst();
user.IsActive = false;
Persist</user><user>.Save(user);

With the addition of the service layer, you now do this.

User user = UserService.RetrieveFirst();
user.IsActive = false;
UserService.Save(user);

It’s somewhat easier to read, and you can now expand the functionality provided by your UserService class — something you couldn’t do before with the generic classes. Of course, you could still use the generic classes, as the service classes inherit from the base RetrieveService<T> and PersistService<T> classes.

As for the unit test generator that comes with the templates, I made some small changes and, more importantly, successfully ran the tests (even tested it against both logging systems).

Sample Project

I don’t have an official distribution available for this yet, but I do have source code for you to download that includes the source code for all ORMapper.* projects, CodeSmith templates, and a small example project based on a single table that I’ve used as a test framework. Feel free to check it out and provide feedback.

Download the sample project (ZIP, 253kb) – includes everything except the WilsonORMapper.dll assembly, which can be downloaded from www.ormapper.net

When will a final distribution be available? I want to test some more, clean up some code, and add some more XML help comments… and get some feedback from the community. Let me know what you think.

(Please don’t send comments via e-mail — post them here!)

CodeSmith templates for WORM updated: log4net and memcached support

I’ve just posted an update to my CodeSmith templates for Wilson’s O/R Mapper. New features include:

* Added the CacheManager static class to provide a simple interface to memcached.
* Added interceptor support for log4net as an alternate to NLog.

Let me know what you think — read the (slightly) updated overview and download the templates here: CodeSmith Templates for Wilson’s O/R Mapper.

Update to CodeSmith templates for Wilson’s O/R Mapper

I just made a small (but important) update to the CodeSmith templates for Wilson’s O/R mapper.

  • 12/1/06: Improved the HashCode() algorithm to avoid potential endless loop situations.

If you use these templates, be sure to download the latest release and update your partial classes.

Minor update to WORM CodeSmith templates

I just made a small update to the CodeSmith templates for Wilson’s O/R Mapper:

11/30/06: The default constructor for the EntityBase class now calls a virtual method, Initialize(). By overriding the Initialize() method in your partial class, you can ensure code will run every time your entity is instantiated. This is useful as it avoids the need to override the base constructor in the generated partial class file, which would be overwritten by the code generation process.

For more details and to download the templates, go to CodeSmith Templates for Wilson’s O/R Mapper.