views:

337

answers:

2

What are best practices to configure following class with spring.NET?

using System.Collections.Generic;
using Edu3.DTOModel;

namespace Edu3.Data.SubsonicProvider.RepositoryFramework
{
    public static class RepositoryFactory
    {
        private static readonly Dictionary<string, object> Repositories = 
            new Dictionary<string, object>();

        static RepositoryFactory()
        {
            Repositories.Add(typeof(ISsoUrlTemplateRepository).Name, 
                new SsoUrlTemplateRepository());
            Repositories.Add(typeof(IPackageSessionNodeRepository).Name, 
                new PackageSessionNodeRepository());
            Repositories.Add(typeof(IPackageSessionNodeFinishedRepository).Name, 
                new PackageSessionNodeFinishedRepository());
        }

        public static IRepository<TEntity> GetRepository<TEntity, TRepository>()
            where TEntity : IEntity
        {
            var interfaceShortName = typeof(TRepository).Name;

            // The provider was in the cache, so retrieve it
            var repository = (IRepository<TEntity>)Repositories[interfaceShortName];

            return repository;
        }
    }
}

I would like to add the repositories with Spring.NET. Is this possible?

+1  A: 

I have the same problem with initializing my application because there doesn't seam to exist a way to call static methods on a (static) class in spring.net. But you can try to make your class non-static try following:

public class RepositoryFactory
{
    private static RepositoryFactory instance;

    private static readonly Dictionary<string, object> Repositories =
        new Dictionary<string, object>();

    private RepositoryFactory()
    {
    }

    public static RepositoryFactory GetInstance()
    {
        if (instance == null)
        {
            instance = new RepositoryFactory();
        }
        return instance;
    }

    public static void AddRepository(object repository)
    {
        Repositories.Add(repository.GetType().Name, repository);
    }
}

with the spring-config:

<objects xmlns="http://www.springframework.net" >

  <object id="RepositoryFactory" type="Edu3.Data.SubsonicProvider.RepositoryFramework.RepositoryFactory, %ASSEMBLY_NAME%" factory-method="GetInstance">
    <property name="AddRepository" value="SsoUrlTemplateRepository" ></property>
    <property name="AddRepository" value="PackageSessionNodeRepository" ></property>
    <property name="AddRepository" value="PackageSessionNodeFinishedRepository" ></property>
  </object>

  <object id="SsoUrlTemplateRepository" type="SsoUrlTemplateRepository, %ASSEMBLY_NAME%" singleton="false"/>
  <object id="PackageSessionNodeRepository" type="PackageSessionNodeRepository, %ASSEMBLY_NAME%" singleton="false"/>
  <object id="PackageSessionNodeFinishedRepository" type="PackageSessionNodeFinishedRepository, %ASSEMBLY_NAME%" singleton="false"/>

</objects>
Fabiano
is this a possible solution? or have you found an other solution in the meanwhile which you could share?
Fabiano
Yes, this is possible solution. I'm still checking another solution. Maybe it's possible with spring expressions... don't know, have to look into it deeper. Will post if I find something.
Lieven Cardoen
+2  A: 

Expose the dictionary as a public property and remove the readonly modifier of the field and don't make your class static. Then use this configuration:

  <object id="RepositoryFactory" type="Edu3.Data.SubsonicProvider.RepositoryFramework. RepositoryFactory, Edu3.Data.SubsonicProvider.RepositoryFramework">
    <property name="Repositories">
      <dictionary key-type="System.Type" value-type="System.Object">
        <entry value-ref="SsoUrlTemplateRepository">
          <key>
            <expression value="T(Edu3.Data.SubsonicProvider.RepositoryFramework.SsoUrlTemplateRepository, Edu3.Data.SubsonicProvider.RepositoryFramework)"/>
          </key>           
        </entry>
      </dictionary>
    </property>
  </object>

  <object id="SsoUrlTemplateRepository" type="Edu3.Data.SubsonicProvider.RepositoryFramework.SsoUrlTemplateRepository, Edu3.Data.SubsonicProvider.RepositoryFramework" singleton="false"/>
BennyM
Thx, will check this in a moment.
Lieven Cardoen
What does Spring.Net behind the curtain? creating an instance of RepositoryFactory?Additional I would suggest to make the default constructor private
Fabiano
Spring.NET creates an instance, so making the default constructor private will make this fail. If you really want to enforce this use a factory method. I'd inject the repository factory in the objects that need to get a reference to a repository.
BennyM
I'm using now this approach and it works with a private constructor. I think Spring.Net uses reflection an as long as there is a default constructor the visibility doesn't matter.
Fabiano