ObjectSpaces - thin?

One of the most innovative things about ObjectSpaces is the fact that your business entities are not required to inherit from any base class. 

 

With every persistence framework I have worked with – this has always been a requirement.  As in this example, EntityBase would provide your O/R mapping and persistence functionality:

 

public class Employee : EntityBase

{

       private int _ID;

       private string _fullName;

             

       public int ID {get {return _ID;} set{_ID = value;}}

       public string FullName{get {return _fullName;} set{_fullName = value;}}

       public Employee()

       {

       }

}

 

 

By not requiring use of a base class – I think Microsoft has done a great job keeping ObjectSpaces as thin and transparent as possible.

 

How was this accomplished?

 

The ObjectSpace classes (driven by map files) consume your custom classes, instead of providing functionality through inheritance.

 

For example to retrieve an employee,

 

ObjectSpace os = new ObjectSpace("map.xml", conn);

ObjectReader reader = os.GetObjectReader(new ObjectQuery(typeof(Employee), "ID = 1234’"));

Employee myEmp = (Employee) reader.Current;

 

Very nice. However, you might say… how is this considered thin? I’m used to instantiating business objects as easily as this:

 

A)  Employee myEmp = new Employee(id);

OR

B)  Employee myEmp = Employee.GetByID(id);

 

Well, the good news is… if you have been using a factory design pattern to instantiate your biz objects (as in B) – then you will be able to encapsulate all of the ObjectSpace classes within your static method (GetByID):

 

Similar to this,

 

public class Employee

{

private int _ID;

       private string _fullName;

             

       public int ID {get {return _ID;} set{_ID = value;}}

       public string FullName{get {return _fullName;} set{_fullName = value;}}

       public Employee()

       {

       }

 

       public static Employee GetById(int ID)

       {

              ObjectSpace os = new ObjectSpace("map.xml", conn);

       ObjectReader reader = os.GetObjectReader(new ObjectQuery(typeof(Employee), String.Format("ID = {0}", ID)));

              return((Employee)reader.Current);

       }

}

 

So, if you have been using a factory creational pattern – perhaps the developers consuming your business objects need not be aware of a conversion to ObjectSpaces at all…. Seems pretty tight to me. Of course, I have not seen examples of inserts/updates using ObjectSpaces yet.  Please comment! 

 

-Mike

 

PDC presentation  , Lucas Bolonese on ObjectSpaces.

5 Comments

  • I'd argue that there's nothing wrong with requiring a base class, but that argument happens day in and day out in the O/R world, so I'll skip it. ;)



    However, I did want to point out one thing. With static methods, like your Employee::GetId, what if you want the object to be part of a transaction? This method is always getting the object from a totally diff. ObjectSpace instance which means it's not going to be included in the transaction of the current object space. If you stayed with the static pattern, you'd always need to pass in an ObjectSpace instance as a parameter which the static method could use to retrieve the Employee object. However, then you run into issues where what if the ObjetSpace passed isn't configured for the Employee object? It gets messy really quick. The best thing to do is to always design a system class, say EmployeeSystem, that contains a private instance of an ObjectSpace and provides basic fetching/updating routines for entities that live within the system, such as Employee, as instance methods. The system then manages the lifetime of the ObjectSpace, loading of the configuration is managed in one place and transaction can be controlled by providing a custom transaction control implementation that basically delegates to the underlying ObjectSpace instance. This also has an added benefit of providing an extra level of indirection which can better abstract you from whatever ORM layer you've chosen.

  • Cripes! I get ripped a new one by Mr. Thona Software O/R mapper tool expert.



    [Thomas T writes]

    I strongly suggest you work with more than one or two persistence frameworks before making hugh statements about what is innovative.



    Did I make a huge statement about what was innovative? I simply opened with a complement to a technology that I was discussing, inviting comments -- I think not deserving of your personal attack.



    [Thomas T writes]

    Yes, and what do they gain with this?



    What do they gain? The ability to introduce a new technology without having to re-write thousands of lines of code to support yet another data access technology. I’m simply trying to highlight the efforts made to keep additions to this evolving framework thin.



    [Thomas T writes]

    I definitly prefer to express my queries where they are decided.



    That’s great. You miss my point entirely. The point is that a factory method can help encapsulate the complexity of actually creating the object. I can do another example w/a factory method that takes a complex query – and then you can express your query wherever you like.



    [Thomas T writes]

    I definitly prefer to express my queries where they are decided - normally in the front end. Simply becaue this is what de-coupling is all about.



    Come on, that’s not what de-coupling is ALL about. In any case, what you’ve done in lowered coupling (a good thing) – but you’ve also lowered cohesion (a bad thing)… An object that knows all the different ways to instantiate & retrieve itself is a highly-cohesive object (at least it’s a contributing factor). You’ve pointed out this same object is more coupled to its consumers. Yes it is.



    Assigning object responsibilities such that cohesion remains high and coupling remains low is the challenge. AND it is also not at ALL the point of this post. Thanks for (trying) to beat me up over it.



    [Thomas T writes]

    I prefer having developers aware that they are hitting the database



    Super. Enjoy that.

  • A comment -



    I don't like the mapping XML files and the reason I don't is because of lazy loading. They lead you into a false sense of security. They lead you to believe you won't have to change your object model.



    Your example is very simplistic. What if Employee had an ArrayList that contains all their direct reports which in turn are Employee objects? If you don't use ObjectSpaces' special lazy load collection, you're query will be nasty and could require many trips to the database. So even though you have an XML mapping file you also have to change your object model.



    Now this is based off just seeing the PDC slides and examples. I haven't actually used ObjectSpaces extensively. Personally I'm trying to get away from Domain Models for RETRIEVING data. I like using sprocs (or dynamic SQL) that retrieves all (or at least most) of the data that is needed for a page.

  • [Justin Rudd writes]

    "Your example is very simplistic. What if Employee had an ArrayList that contains all their direct reports which in turn are Employee objects? If you don't use ObjectSpaces' special lazy load collection, you're query will be nasty and could require many trips to the database."



    Well, I know. The example was simple on purpose. The functionality you describe, though, would be easy to add. Something like this... where Query, passed in could be "EmployeeBossId = XX"...



    public static EmployeeList GetEmployees(string Query)

    {



    ObjectSpace os = new ObjectSpace("map.xml", conn);

    ObjectSet set = os.GetObjectSet(new ObjectQuery(typeof(Employee), Query));

    return((EmployeeList)set);

    }



    Of course I'm not suggesting any of this is best practice.... I'm just saying that it is possible to encapsulate the ObjectSpace stuff so it can be inserted with low impact into an existing application.



    You do make a good point. Its not low-impact to convert your contained collections to a new class:

    public ObjectList EmployeeList = new ObjectList();



    But I dont think you need to...if you currently implement Just-In-Time instantiation, of child collections... just keep doing it the same way... your property calls the method above only if the collection is not loaded....





  • Yes there should realize the opportunity to RSS commentary, quite simply, CMS is another on the blog.

Comments have been disabled for this content.