Porting AC 7 codes To AC Gold

This forum is where we'll mirror posts that are of value to the community so they may be more easily found.
Post Reply
User avatar
mazhar
Master Yoda
Master Yoda
Posts: 5084
Joined: Wed Jul 09, 2008 8:21 am
Contact:

Porting AC 7 codes To AC Gold

Post by mazhar » Tue Jan 22, 2013 6:11 am

There are a number of questions asked about problems faced when attempting to port code to AC Gold that was written for AC7.

When writing AC Gold API we had this thing in mind and we tried our best to keep it backward compatible to preserve most of the custom codes done by end users. There are few major changes and higher chances are that most of the AC7 codes can simply be converted to AC Gold by making these few adjustments.

I am going to explain the changes which are likely to be most common reason for problems you are facing.

1. Token.Instance is changed to AbleContext.Current

Chances are you will be seeing the following error

Error: The name 'Token' does not exist in the current context

In AC 7 we had Token object that provided access on store context. For example like Token.Instance.UserId, Token.Instance.Store etc. This is changed in AC Gold and now you need to use AbleContext.Current to get store context. This the most common error you will see during the porting work and its fix is very simple. Just change Token.Instance => AbleContext.Current

Follwoing code will demonstrante the coding style for both AC 7 and AC GOLD to explain the differance.

Code: Select all

// AC 7
Store = Token.Instance.Store;

// AC 8
Store = AbleContext.Current.Store;
2. StoreSettingCollection is changed to StoreSettingsManager

Chances are you you will be seeing the following error

Error: The type or namespace name 'StoreSettingCollection' could not be found (are you missing a using directive or an assembly reference?)

AC 7 had StoreSettingCollection which gave access on store wide settings. This was strongly typed collection class which had properties on it to set/get store settings. In AC Gold we no longer have strongly typed collection class so StoreSettingCollection is replaced by StoreSettingsManager class. In order to fix this broken piece of code all you need is to change StoreSettingCollection => StoreSettingsManager.

Following code will demonstrate coding style for both AC 7 and AC Gold

Code: Select all


// AC 7
StoreSettingCollection settings = Token.Instance.Store.Settings;

// AC Gold
StoreSettingsManager settings = AbleContext.Current.Store.Settings;

3. No more strongly typed collection classes, instead Gold is using generic lists

Chances are you will be seeing the following error

Error: The type or namespace name '___Collection' could not be found (are you missing a using directive or an assembly reference?)
where ___ can be any entity classs for example Product, Order, Coupon.

AC 7 had strongly typed collection classes to hold 0 or more objects of specific entity class. For example ProductCollection to contain list of products, OrderCollection to contain list of orders etc. This resulted in lot of code files for those collection classes in AC7. In AC gold we using generic lists which are allowing us compile time type safety without separate collection code file for each object. You can fix broken code suffering from this change very easily using following trick.

Simply remove the word Collection from variable declaration and wrap rest of it in IList<---> where --- will be entity type name left after removal of word collection.

Following code demonstrate coding style for AC 7 and AC Gold

Code: Select all

// AC 7
ProductCollection products = ProductDataSource.LoadForCategory(1, false);

// AC Gold
IList<Product> products = ProductDataSource.LoadForCategory(1, false);
4. LoadForCriteria method on DataSource classes is different

Chances are you will be seeing the following error

Error: Argument 1: cannot convert from 'string' to 'NHibernate.ICriteria'

This is bit difficult. In AC 7 we had LoadForCriteria method that used to take where clause string to allow an easy way to quickly run your query having simple where restrictions. In AC Gold since we are using NHibernate this LoadForCriteria now takes Nhibernate ICriteria object. In order to fix it you will have to build and pass nhibernate criteria. If you ever found yourself in this situation i would suggest that you better create and run the criteria object your self instead of passing it to LoadForCriteria it really doesn't make much of difference any beside executing and returning the results. Following code will demonstrate about custom criteria based query in AC 7 and AC Gold.

Code: Select all


// AC 7
ProductCollection products = ProductDataSource.LoadForCriteria("Name LIKE %apple%");

// AC Gold
IList<Product> products = NHibernateHelper.CreateCriteria<Product>()
            .Add(Restrictions.Like("Name", "apple", MatchMode.Anywhere))
            .List<Product>();
5. LSDecimal class is no longer in Gold just use .NET decimal instead of LSDecimal

Code: Select all

// AC 7
LSDecimal price = product.Price;

// AC Gold
decimal price = product.Price;

rpb3
Lieutenant (LT)
Lieutenant (LT)
Posts: 60
Joined: Fri Jan 23, 2009 11:20 am

Re: Porting AC 7 codes To AC Gold

Post by rpb3 » Wed Jul 15, 2015 9:51 pm

This was helpful mazhar... but can you tell me the best way to convert something like this?

Code: Select all

public virtual bool Load(Int32 pCategoryId)
    {
      bool result = false;

      this.CategoryId = pCategoryId;

      //CREATE THE DYNAMIC SQL TO LOAD OBJECT
      StringBuilder selectQuery = new StringBuilder();
      selectQuery.Append("SELECT " + GetColumnNames(string.Empty));
      selectQuery.Append(" FROM my_CategoriesExtended");
      selectQuery.Append(" WHERE  CategoryId = @CategoryId  ");
      Database database = Token.Instance.Database;
      DbCommand selectCommand = database.GetSqlStringCommand(selectQuery.ToString());

      database.AddInParameter(selectCommand, "@CategoryId", System.Data.DbType.Int32, this.CategoryId);


      //EXECUTE THE COMMAND
      using (IDataReader dr = database.ExecuteReader(selectCommand))
      {
        if (dr.Read())
        {
          result = true;
          LoadDataReader(this, dr); ;
        }
        dr.Close();
      }
      return result;
    }
The main thing as you know is that the Token.Instance.Database doesn't exist anymore. Any suggestions?

nadeem
Captain (CAPT)
Captain (CAPT)
Posts: 258
Joined: Tue Jul 31, 2012 7:23 pm

Re: Porting AC 7 codes To AC Gold

Post by nadeem » Thu Jul 16, 2015 2:20 am

You need to Replace

Code: Select all

Database database = Token.Instance.Database;
With

Code: Select all

IDatabaseSessionManager database = AbleContext.Current.Database;
Don't forget to add the following using statement at the top of the page (if it's not already there):

Code: Select all

using CommerceBuilder.Common;

rpb3
Lieutenant (LT)
Lieutenant (LT)
Posts: 60
Joined: Fri Jan 23, 2009 11:20 am

Re: Porting AC 7 codes To AC Gold

Post by rpb3 » Thu Jul 16, 2015 3:35 pm

Yes, I figured that out but I don't think that is what I need. Although that line of code is technically acceptable it doesn't really get me what I want.

I don't believe you can run queries using the IDatabaseSessionManager object.

I think I am going to have to figure out how to do that with NHibernate like Judy talks about here:

viewtopic.php?f=65&t=17153&p=73283&hili ... ase#p73283

I'll have to search for a wiki or some documentation on NHibernate I suppose.

nadeem
Captain (CAPT)
Captain (CAPT)
Posts: 258
Joined: Tue Jul 31, 2012 7:23 pm

Re: Porting AC 7 codes To AC Gold

Post by nadeem » Wed Jul 22, 2015 1:14 am

Sorry for the delay. Try something like this (not tested):

Add the following using statement at the top of the page

Code: Select all

using CommerceBuilder.DomainModel;
using NHibernate;
Update your custom code like this

Code: Select all

public virtual bool Load(int pCategoryId)
{
    //CREATE THE DYNAMIC SQL TO LOAD OBJECT
    StringBuilder selectQuery = new StringBuilder();
    selectQuery.Append("SELECT " + GetColumnNames(string.Empty));
    selectQuery.Append(" FROM my_CategoriesExtended");
    selectQuery.Append(" WHERE  CategoryId = :CategoryId  ");
            
    ISQLQuery query = NHibernateHelper.CreateSQLQuery(selectQuery.ToString());
    query.SetParameter("CategoryId", pCategoryId);

    return query.UniqueResult<bool>();
}

Post Reply