#region Apache Notice /***************************************************************************** * $Revision: 374175 $ * $LastChangedDate: 2006-04-25 19:40:27 +0200 (mar., 25 avr. 2006) $ * $LastChangedBy: gbayon $ * * iBATIS.NET Data Mapper * Copyright (C) 2006/2005 - The Apache Software Foundation * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ********************************************************************************/ #endregion #region Using using System; using System.Collections; using System.Reflection; using Castle.DynamicProxy; using IBatisNet.Common.Logging; using IBatisNet.Common.Utilities.Objects; using IBatisNet.Common.Utilities.Objects.Members; using IBatisNet.Common.Utilities.Proxy; using IBatisNet.DataMapper.MappedStatements; #if dotnet2 using System.Collections.Generic; #endif #endregion namespace IBatisNet.DataMapper.Proxy { /// /// Default implementation of the interceptor reponsible of load the lazy element /// Could load collections and single objects /// [Serializable] internal class LazyLoadInterceptor : IInterceptor { #region Fields private object _param = null; private object _target = null; private ISetAccessor _setAccessor= null; private ISqlMapper _sqlMap = null; private string _statementName = string.Empty; private bool _loaded = false; private object _lazyLoadedItem = null; //private IList _innerList = null; private object _loadLock = new object(); private static ArrayList _passthroughMethods = new ArrayList(); private static readonly ILog _logger = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType ); #endregion #region Constructor (s) / Destructor /// /// Static Constructor for a lazy list loader /// static LazyLoadInterceptor() { _passthroughMethods.Add("GetType"); } /// /// Constructor for a lazy list loader /// /// The mapped statement used to build the list /// The parameter object used to build the list /// The proxified member accessor. /// The target object which contains the property proxydied. internal LazyLoadInterceptor(IMappedStatement mappedSatement, object param, object target, ISetAccessor setAccessor) { _param = param; _statementName = mappedSatement.Id; _sqlMap = mappedSatement.SqlMap; _target = target; _setAccessor = setAccessor; } #endregion #region IInterceptor member /// /// Intercepts the specified invocation. /// /// The invocation. /// The target arguments. /// public object Intercept(IInvocation invocation, params object[] arguments) { if (_logger.IsDebugEnabled) { _logger.Debug("Proxyfying call to " + invocation.Method.Name); } lock(_loadLock) { if ((_loaded == false) && (!_passthroughMethods.Contains(invocation.Method.Name))) { if (_logger.IsDebugEnabled) { _logger.Debug("Proxyfying call, query statement " + _statementName); } //Perform load if (typeof(IList).IsAssignableFrom(_setAccessor.MemberType)) { _lazyLoadedItem = _sqlMap.QueryForList(_statementName, _param); } else { _lazyLoadedItem = _sqlMap.QueryForObject(_statementName, _param); } _loaded = true; _setAccessor.Set(_target, _lazyLoadedItem); } } object returnValue = invocation.Method.Invoke( _lazyLoadedItem, arguments); if (_logger.IsDebugEnabled) { _logger.Debug("End of proxyfied call to " + invocation.Method.Name); } return returnValue; } #endregion } }