Activator.CreateInstance with arguments

Feb 19 2008 3:00 AM

Hi All,

I'm having trouble understanding why the second of the following methods in my repository factory is returning null.

        /// <summary>
        ///
        /// </summary>
        /// <param name="repositoryName"></param>
        /// <returns></returns>
        private Type GetRepositoryType(string domainEntityTypeName)
        {
            Type repositoryType;

            RepositoryConfiguration configuration = RepositoryConfiguration.GetConfig();

            if (configuration.RepositoryMappings.ContainsKey(domainEntityTypeName))
                repositoryType = Type.GetType(configuration.RepositoryMappings[domainEntityTypeName].RepositoryTypeName);
            else
                throw new InfrastructureLayerException(String.Format("Unable to locate {0} repository", domainEntityTypeName));

            return repositoryType;
        }
        /// <summary>
        /// Provides the required repository as an interface, passing in some repository usage information
        /// </summary>
        /// <returns></returns>
        public IBaseRepository<TEntity> GetBaseRepository<TEntity>(string domainEntityTypeName, IRepositoryUsageArgs usageArgs)
            where TEntity : BaseDomainEntity
        {
            Debug.Assert(!String.IsNullOrEmpty(domainEntityTypeName), ToString() + " - domainEntityTypeName cannot be null");
            Debug.Assert(usageArgs != null, ToString() + " - repository usage arguments cannot be null");

            Type repositoryType = GetRepositoryType(domainEntityTypeName);

            IBaseRepository<TEntity> repository = Activator.CreateInstance(repositoryType, usageArgs) as IBaseRepository<TEntity>;

            // Create the repository, and cast it to the interface specified
            return repository;
        }

        /// <summary>
        /// Provides the required repository as an interface, passing in some repository usage information
        /// </summary>
        /// <returns></returns>
        public IBaseRepository<TEntity> GetBaseRepository<TEntity>(string domainEntityTypeName,
                                                                   IRepositoryUsageArgs usageArgs,
                                                                   IRepositoryUsageArgs extraUsageArgs)
            where TEntity : BaseDomainEntity
        {
            Debug.Assert(!String.IsNullOrEmpty(domainEntityTypeName), ToString() + " - domainEntityTypeName cannot be null");
            Debug.Assert(usageArgs != null, ToString() + " - repository usage arguments cannot be null");

            Type repositoryType = GetRepositoryType(domainEntityTypeName);

            // Create the repository, and cast it to the interface specified
            //object[] args = new object[] { usageArgs, extraUsageArgs };

            IBaseRepository<TEntity> repository = Activator.CreateInstance(repositoryType, usageArgs, extraUsageArgs) as IBaseRepository<TEntity>;

            return repository;
        }

As you can see I have split the actual lines of code into more than is need but this is only for debugging purposes.  The first GetBaseRepository works fine, the constructor of the required repository gets called and the usageArgs are passed in fine and is returned instantiated.

Now the second method GetBaseRepository with an 'extra' set of args also works up to a point, in that both usageArgs and extraUsageArgs are instantiated, the repositoryType local variable is set to the required repository type, and when the following call is made

IBaseRepository<TEntity> repository = Activator.CreateInstance(repositoryType, usageArgs, extraUsageArgs) as IBaseRepository<TEntity>;

The constructor of the required repository is called and the arguments are passed in and assigned fine, the local variable holding the repository comes out as null.

As you can see commented out

//object[] args = new object[] { usageArgs, extraUsageArgs };

I've tried simply passing in args which contains both, but still it comes out as null.

In the first method a repository called LookupRepository is created, and is type safe as that is what TEntity comes through as, i.e. Lookup.  As one would expect this repository deals with the retrieval and persistence of a Lookup entity.

The second method creates a CompositeLookupRepository, which deals with a CompositeLookup entity in a similar way.

In the case of CompositeLookup and CompositeLookupRepository they both inherit from Lookup and CompositeLookup respectively.  This could be the problem, however the CompositeLookup repository constructor is called with both usageArgs and extraUsageArgs, and it calls ... : base(usageArgs) and as in the first GetBaseRepository method, and then it deals with setting up the extraUsageArgs in the 'child' repository, and that all works fine also, and no exception is raised, so it deosn't seem to be to do with the actual creation of the repository instantiations, it's just that nothing comes out of the Activator.CreateInstance.

Any ideas, or futher info required, please ask...

Many thanks in advance

Colin
p.s. I realise that the use of a string in this code is sub-optimal and needs a re-factor!