Business Object heirarchy

Business Object heirarchy

Old forum URL: forums.lhotka.net/forums/t/1258.aspx


SonOfPirate posted on Tuesday, September 19, 2006

Another discussion (http://forums.lhotka.net/forums/thread/6411.aspx) has raised the question about the best and proper way to establish a heirarchy of business objects.  Here's a very simplistic example scenario to help illustrate the question:

tblActors
UniqueID: Guid
UserName: String
Password: String

tblCustomers
UniqueID: Guid
Name: String

tblCustomerOrders
CustomerID: FK_tblCustomers
OrderID: FK_tblOrders (not shown)
etc.

tblVendors
UniqueID: Guid
Name: String

tblVendorPurchases
VendorID: FK_tblVendors
PurchaseID: FK_tblPurchases (not shown)
etc.

tblEmployees
UniqueID: Guid
EmployeeNumber: String
PayRate: Decimal

 Again, this is very simplistic but everyone should be able to picture their own scenerio such as this.

The object model follows a similar pattern (simplified for space):

public class Actor : BusinessBase
{
    public Guid UniqueID;
    public string UserName;
    public string Password;
}

public class Customer : Actor
{
    public Guid UniqueID;
    public string Name;
    public OrderCollection Orders;
}

public class Vendor : Actor
{
    public Guid UniqueID;
    public string Name;
    public PurchaseCollection Purchases;
}

public class Employee : Actor
{
    public Guid UniqueID;
    public string EmployeeNumber;
    public Decimal PayRate;
}

While this is a simplistic design, it highlights a number of concepts.  The first of which is why have this heirarchy in the first place.  Well, let's say that we have Customers that are also Vendors.  For accounting purposes we want to consolodate our billing and receivables so that everytime we sell something to that "customer", we are credited the sale price towards our payables account to that "customer" as our vendor.  We need some way to link these two together to recognize that they are a single entity.

All three "entities" (customer, vendor, employee) are able to sign into the companies web application to gain access to their particular information.  As such, all three are specific types of users.  But, simply specifying their security role is not enough as their information is also different.

Another is the more generic question of inheriting one business object from another.  As you can see, the Actor's Guid is potentially lost because the derived object's ID is used instead.  This has come up a number of times when dealing with parent-child relationships.  For instance, an Order object versus a CustomerOrder.  It would be nice to be able to leverage existing code in the Order object when creating the CustomerOrder class rather than having to repeat the work (especially when considering the scope of future changes).  Rocky makes use of the ...Info classes with a link to the original object, but it would be nice if there was a cleaner way to make this happen.  So, in the context of the above scenario, I thought I'd throw this one out there two.

In any event, there are a few of us interested in your thoughts and input on the above scenerio and how best to approach this type of design with the CSLA framework.

Thanks in advance.

skagen00 replied on Tuesday, September 19, 2006

One thing I would say first is that there is a possibility you may consider composition over inheritance (get rid of the inheritance chain you have). That is, you might consider having an Actor class that has the following role objects which may or may not be null:

Employee, Customer, Vendor

That is, an actor (me) could be both a customer and a vendor - or they could be an employee and a customer- etc. Each of these would be child objects of Actor.

In my system, a Profile (Individual or Organization) can have one or many profile roles, such as Vendor, Student, etc. This is pretty analogous to what you're doing. I actually have my profile contain a polymorphic profile role collection. 

If you keep inheritance, I simply wouldn't declare keys in subclasses - they should get their parent class key. For instance, in my example in another post (which you linked this post to), my very base class of Entity<T> defines SystemId and also GetIdValue - I don't declare it in any of the subclasses with new Ids.

 

RockfordLhotka replied on Tuesday, September 19, 2006

Yes, always favor composition (collaboration) over inheritance!

Also, remember to base your object model on behavior, not on your data structures. Your object model should flow directly from your business use cases, not data relationships. As such, an object should contain only the data it needs to fulfill its responsibility and implement its behaviors. And, due to this, an object should feel free to directly pull data from any table or source.

In other words, just because the data allows an actor to be a customer or vendor doesn't mean that you have any use cases where that actually happens. And if it doesn't happen in a use case, then there's absolutely no reason to reflect the concept in your object model.

simon_may replied on Tuesday, September 19, 2006

Funny how OO semantics: inheritance, composition, polymorphism and the rest are nice and stable in ones mind until you introduce the notion of persistance, and particularly when a relational schema is to be the basis of that persistance.

BTW I claim no expertise or particular experience in this area. I have been staggering around blindly in the dark trying to solve these issues for some time as I develop my own tools in an attempt to make my life more productive. (based around CSLA and other bits and pieces).

The best I can do is contribute some modest observations and reasonings of my own. It might help spark useful thoughts in others.

Part of the problem lies in the nature of business object classes, i.e. classes should be defined by behaviour and not the data thay contain. Easy to say but somewhat difficult to clearly stick to as the data has so much impact on the behaviour. Another part of the problem is the that CSLA buxiness objects are not designed with inheritance of business behaviour in mind (I duck as Rocky throws things at me) . A further part is the impedance mismatch between relarional data design and an object model.

Ok, I hear you say, We know  the problems.

Object relational mapping theory is reasonalby well understood. There are basicall three ways in which objects can be mapped:  Table per class, Table per subclass or tabel per class hierarchy. And posibly combinations in parts of an object hierarchy.

This produces one rule that should help you 'Son of Pirate' The object ID should always be inherited from the superclass. If you allow it to be hidden you will be in big trouble. I dont believe you can find a reliable mapping.

Ignoring the Table per class strategy(horribly ineffecient on insert/update) it should be reasonably straightfoward to create data portal code and views and stored procs (or introduce something like nHibernate) that deliver a set of business base derived objects exhibiting inheritance from a data standpoint. Defintion of an associated set of intertaces provide a means to create a set of polymorphic collection objects to manage the business objects

(I am currently developing a code generation approach to take care of most ot the donkey work. for my company)

This does not take care of behaviour. Supporting inherited business methods requies the inheritance of CSLA businessbase derived classes. two things I worry about - what do i lose when i go of the CLSA piste - and worse case will i need to amend the framework (this is a no no)

One idea that is lurking around at the bottom of my brain the thought of building onthe idea of 'normalisation of behaviour'.  Inheritance and polymorpism provide one means of normalisation - but we have problems here. However Rocky showed another way in the project tracker demo. He normalised common behaviour of Role and Assignment into a common class.

I appologise for the unstructured ramble but hopefully it will spark some thoughts in orhers - I am keen to develop a relaiable and systematic way of supporting ORM and behavioural inheritance in CSLA based apps and would be keen to work with ohters to achieve this

Simon

skagen00 replied on Tuesday, September 19, 2006

I just wanted to comment on inheritance and polymorphism and say that it is certainly difficult with generics. But there is always the option to go outside of that with Core.BusinessBase and it eliminates all of the barriers that generics throws into the picture.

I myself approached it while still utilizing generics - I find that I have to introduce a separate factory class to help out, but it works pretty decently. I didn't want to disconnect from the standard approach to the framework usage.

With respect to persistance mucking things up, I have to disagree with you - I have a situation where I have inheritance, composition, and polymorphism all working together in an area and I have not encountered problems with persistance. What I will give you however is that as you start to be "cute" with things, it becomes harder and harder to have a generated persistance layer (stored procedures most specifically).

Thanks for your post!

RockfordLhotka replied on Tuesday, September 19, 2006

Interesting ideas Simon, and I don't disagree (well, except that I do think I show good ways to consolidate behavior Stick out tongue [:P]).

I've been slowly coming to the conclusion that there's a concept missing in the whole dialog. Not just here, but industry-wide.

Everyone is concerned about the UI (MVC, data binding and other technologies as evidence). And everyone is concerned about data interaction (ORM, DataSets and other technologies as evidence).

But there's too little concern about business logic. The actual behavior of the system. It is an afterthought, so the logic gets stuck in the UI, or in stored procedures, or in function libraries.

Look at ASP.NET data binding. If you use the SqlDataSource or ObjectDataSource controls, where do you put the business logic? Seriously! There's no place in the model for that sort of thing. I guess you are supposed to rely on validation controls in the UI, and everything else goes into stored procedures (ugh!).

Look at Windows Forms data binding with a DataSet. Again, where does the logic go? Technically you can use partial classes in a DataTable, but I've spent a lot of time on this, and it is very clearly not a "supported approach" by Microsoft, because they didn't make the mainstream model work. You have to subclass the grid control and implement some other interface-based code to hack it enough to work. So again, you put the code in the UI or stored procedures.

When you get right down to it, this has become my primary focus with CSLA. Sure, I wanted to do mobile objects, and I did. But the primary value of CSLA for most people is that these objects provide a "home" for business logic outside the UI or database.

I think the issue in this thread is one of slight confusion. CSLA objects can be used to implement a data-centric, or "ORM"-driven, object model - but that introduces some complexity because it really has never been one of my goals.

I think a better approach is to use the DataPortal_XYZ methods to do mapping from a "data source" into and out of the behavioral objects.

This "data source" might be the database like I show in the book. But it might be a set of data entity objects that provide a higher level of abstraction above the database.

What I'm getting at is that the design constraints around entity objects are very different from those around business objects. The goal with entity objects is to abstract a set of data concepts and data access, and so it is totally realistic to use inheritance of data to simplify various 1:M data relationships in the database.

But with business objects it is all about responsibility and behavior. It is actually counter-productive to try and use inheritance of data when designing business objects. If you use inheritance at all, it should be to inherit behavior, and even then I think collaboration is usually a better overall solution (because it more clearly enables normalization of behavior).

To put it another way: I think there are two impedance mismatch problems. One is to abstract a database into a set of entity objects - and ORM tools tend to do this quite well. The other is actual mapping of data into and out of business objects, and this is a harder problem to automate in some ways, and this is not an area most ORM tools handle well, or at all. Fortunately, given an abstract data representation, this mapping isn't really hard code to write, so putting it in DataPortal_XYZ methods is not an involved process.

SonOfPirate replied on Tuesday, September 19, 2006

Wow, great discussion.  I'm glad to see that I seem to have sparked such a healthy debate.

The questions of use-cases and if we are dealing with entity objects or business objects were offered up in a previous post and I thought I would address them quickly.

I agree completely that the line between entity and business object becomes blurred very easily because our BO's possess data and are interacting with our data stores.  However, as Rocky explains, the utlimate goal of our BO's is to encapsulate behavior with the data supporting that behavior.  With that said, let me explain that the scenario I described is a real-world scenario for a customer looking to implement a web-interface for their customer, vendors, contractors and employees to access.  The site will integrate with the accounting, ERP and HR packages to provide information for each.  The fact that they do have customers that are also vendors complicates the mix.

So, what we need to be able to do is recognize the type of use from their login information.  skagen00's first post has given me new thoughts on this and I'm considering that we need to flip our model over so that the Actor is at the top with some kind of a pseudo-many-to-many relationship to the other tables (e.g. UserType and UserID identifying the table and UniqueID in that table), but my thoughts are new so they aren't well fleshed out yet.

From the login information, we need to be able to instantiate the appropriate business object to access the requisite information.  Again, I am realizing that our model may be upside down as we need a way to have both the Customer and Vendor objects available when logging in as one of the dual-role users and having the login point at one or the other won't do the trick.

From a behavioral perspective, there is much that is included.  To keep things relatively simple, the purpose of our Actor class (initially) was to have a common location for login information and e-mail address so that our base Actor class could implement a common "SendEmail" method that is used either manually by in-house personnal or by the application to send notifications, etc.  This behavior is common to all users regardless of their "role".  Customers will be able to "Pay their bill" while Employees can "submit a vacation request", etc.  These are examples of the types of different use-cases each type of user has.

I am glad to see that this has had the side benefit of spinning off a discussion on behavior-based and data-centric designs because it is this issue that has caused much lost hair over the last few months trying to make sense of all of this.  For instance, we can have a NotificationMailer class which handles the behavior part of sending the notifications but ultimately it needs to know the recipient.  This takes us back to the Customer, Vender, Employee, Contractor, Actor classes which hold the recipient e-mail address.  On the other hand, since the Actor class knows the e-mail address and is the base class for the others, does it (or not) make sense to then have the Actor class implement a SendEmail method?  Afterall, this is a behavior, right?

So, is it better to create our NotificationMailer which accepts an Actor object and implements the code necessary to send the email and have our Actor object strictly an entity object (assuming no other behaviors for the sake of this discussion)

-or-

Implement the SendEmail method on the Actor object and have it, optionally, make use of the NotificationMailer class passing only the e-mail address to its method and make Actor a business object

-or-

???

This balance, along with managing the interaction between the data model and the object model as we've been discussing are definitely areas are debate.

RockfordLhotka replied on Tuesday, September 19, 2006

Yes, I'm enjoying this thread as well.

To target your SendEmail issue: the key, I think, is to remember the responsibility of each object, and to make sure behaviors (methods, etc.) in that object support only that responsibility.

This is related to an OO concept called cohesion. Cohesion is one of the most subtle and hard-to-grok OO concepts out there. But my take on it is that a given class/object should have methods that relate together in some cohesive, meaningful manner. So a class/object should not have a method that doesn't relate to its other behaviors (not data - behaviors!).

If you are using responsibility-driven design, then the methods of an object should be cohesive around that responsibility.

So you need to ask yourself, "what is the responsibility of Actor?" Is it responsible for sending emails? It doesn't sound like it.

I think your idea of a NofiicationMailer is correct. And it should have a SendEmail method, because I'm guessing that is its responsibility.

That leaves the question of how it can get the email address. I would suggest that interfaces, with their "acts-as" relationship, are a good answer.

An Actor can "act as" an IEmailRecipient. So can a Vendor, a Customer, etc.

This way you don't need inheritance to solve this problem at all. NotificationMailer.SendMail() accepts an IEmailRecipient, which must implement an EmailAddress property or something. Vendor, Customer and other similar classes can implement this interface.

The other thing to remember in all this is that properties are not behaviors. Behind a property there might be behaviors (validation rules, etc.). But a property is not a behavior.

So your Vendor, Customer, etc. can all have an EmailAddress property without duplicating behavior. But if they use a common set of validation rules, then those rule implementations should be normalized into a single place; perhaps EmailValidator or something. The ValdiationRules concept in CSLA allows you to easily link these properties to the common set of rules and away you go.

malloc1024 replied on Tuesday, September 19, 2006

Rocky beat me to the punch, but I will try to add to his response.


A class should only have one reason to change.  This is called the Single-responsibility principle.  Adding a SendEmail method in the actor class violates this principle.  You now have two reasons to change the actor class.  Following the Single-responsibly principle will help you with cohesion. 


Ideally, classes should know as little about other classes.  Passing an actor object to a NotificationMailer object violates this.  This forces any object to inherit from the Actor class just to use the NotificationMailer class.  This is less than ideal for many reasons.  The appropriate way to approach this problem is to pass an interface or string to the NotificationMailer class.  This increases the reusability of the class greatly and makes it easier to use.

SonOfPirate replied on Tuesday, September 19, 2006

Great insight in the last two posts.  I like the IEmailRecipient approach and the clarification on the concepts help.

Looking back at the original post, I am still left wondering how best to approach this scenerio?  I have worked with NHibernate before and delved into some complex compositions but in those cases the common "entities" were just data and possessed no behavior.  I liked the idea presented by skagen00 earlier but am having some trouble wrapping my head around it.  Can you elaborate?

What I am think is that the Actor represents the basic user of the application (principal) with the ability to sign-in/sign-out and represents the user's ID for authorization purposes.  Somehow we need a way to "connect" this to their "profile" information whether it is an Employee, Customer, etc.  From a security role standpoint, this is a straightforward relationship between the Actor and the Role.  So, I am thinking that the database schema would be something like:

tblActors
UniqueID : Guid
UserName : string
Password : string
EmailAddress : string
tblCustomers
UniqueID : Guid
ActorID : FK_tblActors
Name : string
etc.
tblVendors
UniqueID : Guid
ActorID : FK_tblActors
Name : string
etc.
tblEmployees
UniqueID : Guid
ActorID : FK_tblActors
BadgeNumber : string
etc.

 

skagen00 replied on Tuesday, September 19, 2006

Hello, if it helps you to talk on the data level, here's how my data is structured.

Profile table has child tables of Individual and Organization

ProfileRole table has child tables of ProfileRoleVendor, ProfileRoleStudent, etc.

ProfileRole has a foreign key to Profile.

Overall I think all of this is consistent with what you have.

With respect to the class, if you have a class like Actor and you only want each actor to serve one role in the system, then perhaps you have Actor contain an IActorDetail. IActorDetail would be implemented in the Customer, Vendor, and Employee classes. IActorDetail might require IEmailReceipient too (inherit).

You may make this member in the Actor class (that holds the child object of IActorDetail) hidden and just expose properties off the Actor class, basically displaying properties of the interface. I'm never as pure as I should be when implementing design patterns, but this is kind of the "strategy" design pattern. You essentially are morphing the behavior of the Actor class by allowing various implementations of IActorDetail to be swapped into the object.

On your root object fetch, you'll need to load the right ActorDetail, which has it's own knowledge of how to DeleteSelf, Update, and Insert among other behaviors and properties as defined by the IActorDetail interface.

Anyone feel free to correct me if I've mispoke.

 

 

 

 

SonOfPirate replied on Tuesday, September 19, 2006

Sorry, actually had some editor problems with the last post and was cut off, but looks like it turned out okay anyway.

I'm still not entirely with you on the design.  Here's where my thoughts are now:

I can create a Customer object and get access to the login information via composition by joining the tblCustomers and tblActors table.  That's no problem when coming at it from the Customer.  (Same with Vender, Employee, etc.)

I have addressed the multi-role issue for the accounting side of things by consolodating the account so that the user/Actor will only have one account assigned and all transactions whether they are as a Customer or Vendor are posted to this same account.  So, for this use-case, I really don't care what the user is and can access the Account from the Actor's UniqueID.  However, the ActorID is getting lost in the join and only the Customer's UniqueID is being held in my object, so I have no way of locating the Account...

I need to give more thought to how the user's profile will be managed when they exist in more than one capacity (e.g. Customer and Vendor) since things like the name and, presumably, billing and mailing addresses, etc. would be the same.  The model may be over-complicated in that the distinction is more or a security role than data or behavioral.  In other words, when we want to see a list of Vendors, perhaps we are looking for users in the Vendors role rather than having a Vendors table. 

Can you clarify what you mean by "'x' table has child table of..."?  I think that's where I am uncertain what you are describing (we all have our own semantics and sometimes they don't translate well to another's).

skagen00 replied on Tuesday, September 19, 2006

When I say child table, that means that:

Profile (contains common data elements to individuals and organizations)

Individual (contains individual specific data elements, foreign keys to Profile)

Organization (contains organization specific data elements, foreign keys to Profile)

I'm using the term child table to describe what Individual and Organization are.

In the same respect, ProfileRole contains data elements to all role types - such as perhaps "IsActive", "Comments", etc.

ProfileRoleVendor contains data elements specific to vendor and foreign keys to ProfileRole.

SonOfPirate replied on Tuesday, September 19, 2006

Thanks for clarifying.  That is what I figured, just wanted to make sure I was on the same page.

 

simon_may replied on Wednesday, September 20, 2006

Boy! when this forum gets its teeth in to something...... great stuff.

skagen00: you are of course quite right about persistance mucking things up (it was not an altogether serious remark more an observation of my thought processes). I like you do not want to modify the CSLA framework and would be very interested in a little more detail on how you tackled the inheritance/generics issue with the factory class solution.

Rocky your point about the lack of concern for business logic is spot on. It is frustrating that (in the main) those commisioning software development can only relate to the visual. However, this is reality and we must deal with it. That is why I am particularly keen on the CSLA framework. To my mind it formalises the way in which business logic can be implemented without taking the visual aspects into account and once completed I can sit down with the customer and show him or her how we can bring this logic to life through the human computer interface of their choice. So much for the dream.

My goal is to translate the specification of the business rules into deployable logic in the most effiecient manner hence the desire to model the required behaviour in OO terms and implement this behaviour as CSLA based business logic/objects

I am sure that for everyone the learning curve is fairly steep. Understanding guiding concepts such as the single-responsibilty principle, cohesion, behaviour driven design and so-on is easy at the surface level but that is a whole world away form having the experience and knowhow of how to apply them to real life situations. Scearioios, examples and discussions such as this are invaluable to the learning process.

Having said all that and returning to Son of Pirate's example. Surely the Actor should not be responsible for managing user authorisation data (system security data) together with business information such as an email address (business communication data). This seems to break the single-responsibility principle in addition making them one and the same reduces on going flexibility.

Anyway just some thoughts

Simon

 

SonOfPirate replied on Wednesday, September 20, 2006

Interesting points, Simon.  Are you then suggesting that we have a "user" object responsible for security and a separate object that handles the profile requirements?  I can see how this makes sense but am back to the same question of "connecting" the two.

Extending the thought process a little, I like this concept because it makes more sense to not directly couple the two as we may want to have profiles that are not "users" per se - kinda like the Active Directory version of Users vs. Contacts.  Only difference is that the User is extended with login credentials.  I can see setting this up in the DB using a FK relationship from tblUsers (say) to tblContacts, but I'm still not sure how to handle it from the BO standpoint.

Again, I need to be able to display the user's profile information based on their log-in credentials (identity).  So, doesn't that behavior mean that there is a single responsibility here?

simon_may replied on Wednesday, September 20, 2006

SoP. Yes I am suggesting two objects (on assumptions that I shouldn't really make) and without examining the application objectives and use cases. However questions that occur to me include: do customers and vendor map to people?  To my mind they map to organisations that in term will provide contacts. Surely it is the contacts that have identities and use the system. I you lock a user (security) to an Actor (commercial) then you lose the ability to provide different contacts with different levels of access to the data pertaining to the organisation. Example, the app provides access to both order data and financial data. The customer or vendor may not want all of their staff to have unfettered access to financial data connected with their company. If this is never going to be the case then you can combine the two into one object. As I say I may well be off the mark.

As to maintianing a link this would depend on how the relation would be defined. A 1 to 1, n to 1, 1 to n or m to n. 1 to 1 and 1 to n indicate a component or child type relationship.

the login identity can be extended to reference the actor profile that it handles.

I hope this makes sense

Simon

SonOfPirate replied on Wednesday, September 20, 2006

Simon, another valid point.  The person logging in really wouldn't be the Customer or Vendor but their agent - a Contact with login rights.  And, as you said, we may have Contacts that do not have access or have different security priviledges to the data.  I will have to add these use cases to the model as they much more accurately describe what is going on.

Another thought that comes to mind is that not all of the application's users will necessarily be Contacts for Customers and/or Vendors but could be Employees or Contractors (a Contractor having just a subset of data as an Employee).  So I would really have two (if we role Employees and Contractors into one for now) types of users with different data AND different access that needs to be discerned from the common login information...

Does anyone know how Active Directory manages this?  I mean there are three types of "accounts" in AD: Contacts, Users and Mail-Enabled Users.  A User is a Contact with login rights (data) and a Mail-Enabled User is a User with mail-related properties.  When I login, how do we know to instantiate the Mail-Enabled User as opposed to a regular User?  Or when I do a lookup, how do we know to return a User versus a Contact object?  And do we implement inheritance here or are we still thinking composition?

(Hopefully this scenerio will work better since I think we've worked most of the kinks out of the original!)

In security terms, we return an IPrincipal but at the point of instantiation, the application had to know the actual type of the object we wanted.  Is this as simple as a "UserType" flag or is there another approach that may better approximate/emulate what AD does to accomplish the same thing?  Given that AD is extensible, I have to think that the flag approach is out because it would require the app to change to add another case to the switch/Select Case statement.

So, here's the question of the hour: How would YOU create your own Active Directory app???

This models exactly what I'm trying to do.  (Sorry it took so long to get my brain there!)

 

simon_may replied on Wednesday, September 20, 2006

SoP, So glsd you are making progress ;).

In security terms, we return an IPrincipal but at the point of instantiation, the application had to know the actual type of the object we wanted.  Is this as simple as a "UserType" flag or is there another approach that may better approximate/emulate what AD does to accomplish the same thing?  Given that AD is extensible, I have to think that the flag approach is out because it would require the app to change to add another case to the switch/Select Case statement.

I am not quite sure of what you are getting at here. But surely you can extend either the identity or probably better the actor with the type of the object that owns it (cusotmer, vendor,....) and its identifier. Then you can use a litttle reflection magic to instanitate it given the key. What is the essence the use case that requires the object instance, i.e. what are you going to do with it then?

Simon

SonOfPirate replied on Wednesday, September 20, 2006

Let's run with the AD scenario...  Let's say I want someone to be able to login and view/edit their account information.  If they are a User, then there will be no mail related information presented; if they have an e-mail account (are a Mail-Enabled User), then that information is available.

I'm wondering how AD handles the differences.  When you install Exchange and it makes its schema changes to AD, does it add mail-related fields to every user and just leaves them blank for users with no mailbox setup?  I.e. when you create a new user and get prompted whether you want to set up a mailbox for the user, what happens behind the scenes when you say "yes" versus "no"?  Are we dealing with two different objects or one object with a bunch of empty properties when we say "no"?

And are we dealing with three separate objects (Contact, User and MailUser) or just one with all of the properties required for all three?  If separate, is their a heirarchy where User is derived from Contact and MailUser is derived from User? Or are we duplicating code?

 

simon_may replied on Wednesday, September 20, 2006

SoP, I know very little about AD but a quick glance at the various tomes on my bookshelf connected with AD fail to mention these user types specifially. An AD user is defined by a set of attributes which will include data of various sorts: contact info, email info, departmental info, (so these terms may just refer to examples of how a user can be defined). All depends on the schema definition as with any database. So I am not sure you will have to deal with different object types. Just design a user object that maps data into its instance as one would do with relational data and business objects. As I say I am new to AD but always interested in these issues.

Simon

Copyright (c) Marimer LLC