Hi All,
I wrote an article a while ago about how I hacked and slashed my way through the CS SDK to extend user data and store that new data in columns in the cs_UserProfile table in CS here:
http://proactivelogic.com/blog/index.php/2007/11/03/extending-community-server-2007-user-profiles-and-vista-setup/
I have been relooking at this approach and I have an idea on a better way to deal with the data layer, that would allow you to NOT update the core CS code. I need to test this out, but I don't see why it would not work yet
I'm posting this up for some early brainstorming feedback.
The pros are: No CS core code updates, enables enlisting in transactions with CS data updates and your own custom data updates
The cons are: Round trips to the database for any call with extended data, longer locks on data
Looking at the pros and cons, I think this plan is worth it, and the perf hit most likely going to be minimal.
Here is my plan that I will code up and test sometime this weekend:
I noticed that since CS is using a provider model for the data, we can plugin our own provider:
<add
name = "ProactiveLogicCommonDataProvider"
type = "ProactiveLogic.CS.Data.PLSqlCommonDataProvider, ProactiveLogic.PLSQLCommonDataProvider"
connectionStringName = "SiteSqlServer" databaseOwnerStringName = "SiteSqlServerOwner"
/>
Since I want to make use of the existing CS SQL code already, and only tie in where needed, derivation seems to be the right implementation choice:
public class PLSQLCommonDataProvider: CommunityServer.Data.SqlCommonDataProvider
{
public PLSQLCommonDataProvider(string databaseOwner, string connectionString) : base ( databaseOwner, connectionString)
{
}
}
Then in order to enlist CS and our code in the same transaction, the Transaction Scope class could be used:
public class PLSQLCommonDataProvider: CommunityServer.Data.SqlCommonDataProvider
{
public PLSQLCommonDataProvider(string databaseOwner, string connectionString) : base ( databaseOwner, connectionString)
{
}
public override CommunityServer.Components.User CreateUpdateDeleteUser(CommunityServer.Components.User user, CommunityServer.Components.DataProviderAction action, bool createLocalUserOnly, out CommunityServer.Components.CreateUserStatus status)
{
CommunityServer.Components.User retUser = user;
// implicitly enlist CS and my code in the same transaction
using (System.Transactions.TransactionScope trans = new System.Transactions.TransactionScope())
{
base.CreateUpdateDeleteUser(user, action, createLocalUserOnly, out status);
string someKey = user.GetExtendedAttribute("SomeDataKey");
// use extended attributes passed from the UI and call your own SQL code here
// would need some error handling and updating of the output status
trans.Complete();
}
return retUser;
}
}
For me this would enable binary reuse of CS, enable extended data to be stored in new columns, and allow that data to be queried efficiently for searches and other lookups on this extended data.
Any thoughts?
Cheers,
Jon