Custom Container Classes

A few years ago I wrote an application using custom entity objects to pass information between my DAL and BLL layers. The object architecture was very basic and was almost a 1-1 relationship to my database schema. My design is getting somewhat complex so I’m going back to do some refactoring. I’m wondering if creating custom container classes for some of my objects is worth the effort or even necessary.

For instance, I have a Player class in my BLL that contains all of the properties and methods related to a Player:

  • public bool PlayGame(int playerID)
  • public bool GetYearlyStats(int playerID, string seasonCode)

but I also have lots of methods which seem like they may be suitable for a container class

  • public static List<Player> GetPlayers(string sportCode, string firstName, string lastName)
  • public static List<Player> GetPlayers(string sportCode, string seasonCode, bool includeRetired)
  • public static List<Player> GetPlayers(string sportCode, string seasonCode, string teamCode, bool includeRetired)
  • public static List<Player> GetPlayers(string sportCode, string seasonCode, string teamCode, bool includeRetired)
  • public static int InsertPlayer(int playerID, string sportCode, string positionCode, string firstName, string lastName, string middleName, string teamCode, int number, DateTime firstYear, int statMapID, bool retired)
  • public static bool UpdatePlayer(int playerID, string sportCode, string positionCode, string firstName, string middleName, string lastName, string teamCode, int number, DateTime firstYear, int statMapID, bool retired)
  • public static bool DeletePlayer(int playerID)

Is there any value in creating a container ‘PlayerBin’ class or something similar to contain all of the methods which just return collections of Players, or even the CRUD methods for a Player? Outside of better organization and intuitiveness, would there be any other advantages to splitting this Player class into 2 separate classes?

I like to look at it from a separate view and usually ask myself, would I test these methods differently than the others?

If my answer is yes, I break them out into a container class because then the tests at least for that class would all be similar, same with the object.

Keep in mind a container class is useful from a testing/mocking standpoint (and dependency injection), so you can swap out the logic for getting players from a different data source without having to modify your Player object. So to have that ability, you would need to make sure your Player object has no dependency to a database, it doesn’t interact with one in any way, shape or form. The container class would handle all interactions, so if you switch from SQL Server to No SQL or MongoDB, or Oracle, you just have to create a new container class.

“Container” is really the way to go here – much better to have something with the sole responsibility of database interaction rather than embedding that function into entities or strewing it about the app.

I’d agree with wwb here. Though I wouldn’t call it a container, but rather a repository.

The difference between the two sets of methods you listed is that the first two methods act upon the player instance they are part of, the others are crud operations that operate on one or more players. Methods like GetX, Inset, Update and Delete, don’t truly belong on a singular entity because you will run into problems with batch processing. If placed on a singular entity, calling insert on several entities at once would involve a loop, and multiple calls. This results in multiple db calls. Place your crud operations in a separate class, so that you can act upon entire lists of objects, and wrap the call in a transaction.

Is there some type of pattern for how I should create a custom ‘Players’ repository class in C#? Essentially these would be collections (Lists preferably) of Player objects.

I guess where I get confused is in the grey area. For instance what if I already have an instance of a Player object and I need to update one of this parameters in the database? For even a single instance you’re saying I should pass this object to the repository class for update:

public class PlayerRepository {
public bool UpdatePlayer(int playerID, string firstName, string lastName, etc…) {}

}

I guess this also eliminates the ability to call an instance member of the player to update, i.e. myPlayer.Update().

From the level of your questions, I am going to assume you are not using an object relational mapper (ORM). Therefore, here is a really simple example using a base class and a proxied repository.

oops… sample code deletd, I forgot which forum I was in. LOL

But to answer your actual question: yes, calling player->Update defeats the purpose of encapsulation and separating the concerns of your business logic (the player class) and those of persistence (the repository). Your business entities should have no knowledge of how or where they are being persisted.

No, no ORM. I’m using custom entity/domain objects. I guess where things get a little tricky is that almost all of the methods in my domain objects either read or write to the database, so creating collection objects for everything seems like overkill.

So let’s say I need to bind a collection of Players to a grid based on a particular Sport. Essentially I need to query the database for all Players, pasing in the sport, and return a collection of Players. This seems to me like a repository request, so in this scenario should the UI skip the Player business object altogether and call the PlayerRepository class to get this data? Or, should the UI always call business objects which would subsequently call the repository classes to retreive the data?

I would likely go through the Sport Business Object. Passing in the sport name, the business object validates it is a valid sport name (or at least is an acceptable string that could be a valid sports name), then it passes the sport name to the Repository object to get the collection.